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

37
.gitignore vendored Normal file
View File

@@ -0,0 +1,37 @@
!.gitignore
# iOS Ignores
.DS_Store
*.swp
*~.nib
build/
Target/
*.pbxuser
*.perspective
*.perspectivev3
*.mode1v3
*mode2v3
xcuserdata
#MonoTouch Ignores
*.userprefs
bin/
obj/
*/bin/*
*/obj/*
*/*/bin/*
*/*/obj/*
*/_ReSharper.*/*
*.user
*.suo
*.pidb
*.userprefs
#*.Designer.cs
#*.designer.cs
*.DS_Store
*.db

View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PhoneHome.Lib.Assembly;
// Downloaded from
// http://www.codeproject.com/Articles/2670/Accessing-alternative-data-streams-of-files-on-an
using Trinet.Core.IO.Ntfs;
using System.IO;
namespace PhoneHome
{
/// <summary>
/// Wrapper class arround Alternate Data Streams
/// * IMP * Registrate 'Later' Medisoft Demo Registration Work-arround
/// Medisoft has a 30 day trial where they don't enter a serial number. However, this can
/// be bypassed, since registration is terrible at what it does. So we must make sure that
/// the 30 days haven't passed, and we deal with it here with PhoneHome via AlternateStreams
/// </summary>
internal static class AlternateDataStreamWrapper
{
/// <summary>
/// Read the Timestamp found in the Alternative Stream
/// </summary>
/// <returns>Dt found or DT.Min (if none found)</returns>
internal static DateTime ReadDateTimeStamp()
{
try
{
string s_curDir = Path.GetDirectoryName(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileNameNPath(AssemblyW.AssemblyST.Executing));
SafeNativeMethods.Win32StreamInfo s_streamInfo = new SafeNativeMethods.Win32StreamInfo() { StreamAttributes = FileStreamAttributes.None, StreamName = "phdt", StreamSize = 20, StreamType = FileStreamType.Data };
AlternateDataStreamInfo adataStream = new AlternateDataStreamInfo(s_curDir, s_streamInfo);
using (FileStream fs = adataStream.OpenRead())
using (StreamReader sr = new StreamReader(fs))
{
string strLine = sr.ReadLine();
DateTime dtFound = DateTime.Parse(strLine);
return dtFound;
}
}
catch (Exception e) { string Message = e.Message; }
return DateTime.MinValue;
}
/// <summary>
/// Write the passed in Timestamp to the Alternative Stream
/// </summary>
/// <param name="dtStamp">Timestamp to write</param>
internal static void WriteDateTimeStamp(DateTime dtStamp)
{
try
{
string s_curDir = Path.GetDirectoryName(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileNameNPath(AssemblyW.AssemblyST.Executing));
SafeNativeMethods.Win32StreamInfo s_streamInfo = new SafeNativeMethods.Win32StreamInfo() { StreamAttributes = FileStreamAttributes.None, StreamName = "phdt", StreamSize = 20, StreamType = FileStreamType.Data };
AlternateDataStreamInfo adataStream = new AlternateDataStreamInfo(s_curDir, s_streamInfo);
using (FileStream fs = adataStream.OpenWrite())
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(dtStamp.ToShortDateString());
}
}
catch (Exception e) { string Message = e.Message; }
}
}
}

839
@integrate/App.xaml.cs Normal file
View File

@@ -0,0 +1,839 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using Watchdog.WatchdogLib.File;
using WatchdogLib.Tools;
using Watchdog.WatchdogLib.Process;
using Watchdog.WatchdogLib.WinForms;
using Watchdog.WatchdogLib.Assembly;
using WatchdogLib.File;
using System.Reflection;
using Watchdog.WatchdogLib.Other;
using Watchdog.WatchdogLib.Monitor;
using System.Diagnostics;
using Forms = System.Windows.Forms;
using Watchdog.WatchdogLib.Net;
using System.IO;
using System.Net;
namespace Watchdog
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
/// <summary>
/// Main Application Object
/// </summary>
public App()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
#region Application Constants
// Application Constants
internal static readonly string APPLICATION_NAME_SHORT = AppResx.GetString("APPLICATION_NAME_SHORT");
internal static readonly string APPLICATION_NAME_LONG = AppResx.GetString("APPLICATION_NAME_LONG");
internal static readonly string SUPPORT_PHONENUMBER = AppResx.GetString("SUPPORT_PHONENUMBER");
internal static readonly int APPLICATION_VERSION_MAJOR = AssemblyW.GetAssemblyVersion(AssemblyW.AssemblyST.Executing).Major;
internal static readonly int APPLICATION_VERSION_MINOR = AssemblyW.GetAssemblyVersion(AssemblyW.AssemblyST.Executing).Minor;
internal static readonly int APPLICATION_VERSION_BUILDNUMBER = AssemblyW.GetAssemblyVersion(AssemblyW.AssemblyST.Executing).Build;
internal static readonly int APPLICATION_VERSION_REVISION = AssemblyW.GetAssemblyVersion(AssemblyW.AssemblyST.Executing).Revision;
internal static string APPLICATION_VERSION { get { return (APPLICATION_VERSION_MAJOR.ToString() + "." + APPLICATION_VERSION_MINOR.ToString() + "." + APPLICATION_VERSION_BUILDNUMBER.ToString() + "." + APPLICATION_VERSION_REVISION.ToString()); } }
/// <summary>
/// This is the Product ID Generated for our Product via ClickOnce and our Certificate.
/// As long as the Certificate Stays the same This ID stays the same.
/// ~we are using this to overide the uninstall icon in Add/Remove * Branding *
/// </summary>
internal static readonly string APPLICATION_PRODUCT_CLICKONCE_ID = "6f02138d8632343a";
internal static readonly string APPLICATION_PRODUCT_CLICKONCE_URL = "http://www.medisoft.com/Watchdog/Publish/Watchdog.application";
internal static string APPLICATION_CLICKONCE_PUBLISHER { get { return AssemblyW.GetAssemblyCompany(AssemblyW.AssemblyST.Executing); } }
internal static string APPLICATION_CLICKONCE_PRODUCT { get { return AssemblyW.GetAssemblyProductName(AssemblyW.AssemblyST.Executing); } }
internal static string APPLICATION_CLICKONCE_STARTMENU_LINK
{
get { return string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Programs), "\\", APPLICATION_CLICKONCE_PUBLISHER, "\\", APPLICATION_CLICKONCE_PRODUCT , ".appref-ms"); }
}
// Default Log File Settings
internal const int LOG_FILE_FILE_SIZE_IN_MB = 2;
internal const int LOG_FILE_NUM_OF_BACKUPS = 4;
// Log File Constants
internal static readonly string FILE_EXTENSION_LOG_DEFAULT = AppResx.GetString("FILE_EXTENSION_LOG_DEFAULT");
internal static readonly string LOG_NAME_APPMAIN = AppResx.GetString("APPLICATION_NAME_SHORT");
// Application Files / Dependencies
internal static string APP_LOG_FILENAME { get { return (LOG_NAME_APPMAIN + "." + FILE_EXTENSION_LOG_DEFAULT); } }
internal static string APP_LOG_FILENAMEANDPATH
{
get
{
// Make sure Subpath begin|end with a slash, as needed
string commondir = PathNaming.PathEndsWithSlash(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string subpath = PathNaming.PathBeginsWithNoSlash(PathNaming.PathEndsWithSlash(AppResx.GetString("LOG_FILE_SUBPATH")));
string filename = LOG_NAME_APPMAIN + "." + FILE_EXTENSION_LOG_DEFAULT;
return (commondir + subpath + filename);
}
}
internal static string APP_LOG_PATH
{
get
{
// Make sure Subpath begin|end with a slash, as needed
string commondir = PathNaming.PathEndsWithSlash(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string subpath = PathNaming.PathBeginsWithNoSlash(PathNaming.PathEndsWithNoSlash(AppResx.GetString("LOG_FILE_SUBPATH")));
return (commondir + subpath);
}
}
internal static string APP_XML_DS_FILENAME { get { return AppResx.GetString("XMLCONFIG_FILENAME"); } }
internal static string APP_XML_DS_FILENAMEANDPATH
{
get
{
// Make sure Subpath begin|end with a slash, as needed
string commondir = PathNaming.PathEndsWithSlash(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string subpath = PathNaming.PathBeginsWithNoSlash(PathNaming.PathEndsWithSlash(AppResx.GetString("XMLCONFIG_FILE_SUBPATH")));
string filename = AppResx.GetString("XMLCONFIG_FILENAME");
return (commondir + subpath + filename);
}
}
internal static string APP_XML_DS_PATH
{
get
{
// Make sure Subpath begin|end with a slash, as needed
string commondir = PathNaming.PathEndsWithSlash(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string subpath = PathNaming.PathBeginsWithNoSlash(PathNaming.PathEndsWithNoSlash(AppResx.GetString("XMLCONFIG_FILE_SUBPATH")));
return (commondir + subpath);
}
}
internal static string APP_INI_SETTINGS_FILENAME { get { return AppResx.GetString("INISETTINGS_FILENAME"); } }
internal static string APP_INI_SETTINGS_FILENAMEANDPATH
{
get
{
// Make sure Subpath begin|end with a slash, as needed
string commondir = PathNaming.PathEndsWithSlash(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string subpath = PathNaming.PathBeginsWithNoSlash(PathNaming.PathEndsWithSlash(AppResx.GetString("INISETTINGS_SUBPATH")));
string filename = AppResx.GetString("INISETTINGS_FILENAME");
return (commondir + subpath + filename);
}
}
internal static string APP_INI_SETTINGS_PATH
{
get
{
// Make sure Subpath begin|end with a slash, as needed
string commondir = PathNaming.PathEndsWithSlash(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData));
string subpath = PathNaming.PathBeginsWithNoSlash(PathNaming.PathEndsWithNoSlash(AppResx.GetString("INISETTINGS_SUBPATH")));
return (commondir + subpath);
}
}
#endregion
#region Application Help
// Application's Main Help Object
internal static CHMFile chmhelp = null;
#endregion
#region Xml Configuration
// Application's Main Xml Object
internal static MonitorDataStore xmlfile = null;
#endregion
#region Ini Configuration
// Application's Main Ini Object
internal static INIFile inifile = new INIFile(APP_INI_SETTINGS_FILENAMEANDPATH, typeof(Ini_Setting));
internal enum Ini_Setting
{
MonitorSettings__Start_With_Windows,
MonitorSettings__Monitor_On_Start,
MonitorSettings__Max_Fail_Count,
MonitorSettings__Max_Fail_Count_Per_Hour,
MonitorSettings__Default_Exe_Running_Filter,
MonitorSettings__Default_Services_Names_Running_Filter,
MonitorSettings__Sheduler_StartDateTime,
MonitorSettings__Sheduler_RepeatEveryNHoursOrMinutes,
MonitorSettings__Sheduler_RepeatIsHour,
MonitorSettings__Sheduler_LastRun_DateTime,
MonitorSettings__Scheduler_Restarts_Services,
MonitorSettings__ShedulerBackup_StartDateTime,
MonitorSettings__ShedulerBackup_ForDurationNHoursOrMinutes,
MonitorSettings__ShedulerBackup_DurationIsHour,
MonitorSettings__ShedulerBackup_LastRun_DateTime,
MonitorSettings__ShedulerBackup_StopInsteadOfPause,
MonitorSettings__ShedulerBackup_StopServices,
WindowSettings__AboutWindow_TopLeft,
WindowSettings__SettingsWindow_TopLeft,
WindowSettings__LogViewerWindow_TopLeft,
WindowsSettings__LockWorkstation_With_Windows,
WindowsSettings__AutoLogin_With_Windows,
WindowsSettings__CreateExeHardLink_In_RootPath,
EmailSettings__EnableEmailNotifications,
EmailSettings__SmtpServer,
EmailSettings__SenderEmail,
EmailSettings__ReveiverEmail,
EmailSettings__SmtpPort,
EmailSettings__SmtpRequiresAuth,
EmailSettings__SmtpRequiresSSL,
EmailSettings__SmtpUsername,
EmailSettings__SmtpPassword,
EmailSettings__Custom_Message_Text,
}
// Wrapper class arround Ini Settings
internal static Settings setting = new Settings();
#endregion
#region Command Line Parameters
// Application's CmdLine Parser
internal static CMDline cmdline = new CMDline(typeof(App.CommandLine_Option), typeof(App.CommandLine_Flag));
/// <summary>
/// CommandLine Flags for Application
/// </summary>
public enum CommandLine_Flag
{
START,
PAUSE,
RESTART,
RESTART_ALL,
STOP,
STOP_ALL,
SHOW_PROCESSES,
SHOW_SERVICES,
LOCK,
RUNASSERVICE,
UNINSTALL,
}
/// <summary>
/// CommandLine Options for Application
/// </summary>
public enum CommandLine_Option
{
ADD_SERVICE,
REMOVE_SERVICE,
ADD_PROCESS,
REMOVE_PROCESS,
}
#endregion
#region Logging Configuration
// Application's Main Log Object
internal static Logging log = null;
/// <summary>
/// Create a Logging_Configuration Object with Default Application Settings
/// </summary>
/// <param name="LogFileNameNPath">Specify the LogFile and Path to Log to</param>
/// <param name="Detail">Specify Logging Details Setting</param>
/// <param name="UseExclusiveFileLock">true, to only allow exclusive (one process) access to file</param>
/// <returns>a Logging_Configuration object to use Utilities.GenericUtilities.File.Logging</returns>
//private static Logging_Configuration CreateDefaultLoggingConfiguration(string LogFileNameNPath, Logging_Detail Detail = Logging_Detail.ERROR, bool UseExclusiveFileLock = false)
private static Logging_Configuration CreateDefaultLoggingConfiguration(string LogFileNameNPath, Logging_Detail Detail, bool UseExclusiveFileLock)
{
Logging_Configuration config;
config.LogFileNameNPath = LogFileNameNPath;
config.maxFileSizeInMB = LOG_FILE_FILE_SIZE_IN_MB;
config.numOfBackupLogFiles = LOG_FILE_NUM_OF_BACKUPS;
config.Detail = Detail;
config.UseExclusiveFileLock = UseExclusiveFileLock;
return config;
}
/// <summary>
/// Responsible for creating the AppMain Logging Object
/// </summary>
public static Logging CreateAppMainLogging()
{
// Log FileNameNPath * Debug mode set logging level to Debug, Release to Info *
#if DEBUG
return Logging.AddGlobalLoggerConfiguration(LOG_NAME_APPMAIN, CreateDefaultLoggingConfiguration(APP_LOG_FILENAMEANDPATH, Logging_Detail.DEBUG, false));
#else
return Logging.AddGlobalLoggerConfiguration(LOG_NAME_APPMAIN, CreateDefaultLoggingConfiguration(APP_LOG_FILENAMEANDPATH, Logging_Detail.INFO, false));
#endif
}
/// <summary>
/// Retrieve the AppMain Logging Object, It must have been created by calling CreateAppMainLogging()
/// </summary>
/// <returns></returns>
public static Logging GetAppMainLogging()
{
return Logging.GetLogger(LOG_NAME_APPMAIN);
}
#endregion
#region Message Box Configuration
/// <summary>
/// We also want to initialize the MsgBox Class here
/// </summary>
public static void ConfigureAppMainMsgBox()
{
// Fatal Errors
MsgBox.MsgBox_FatalErrorTitleHeader = AppResx.GetStringFormated("APPLICATION_FATAL_ERROR", APPLICATION_NAME_SHORT);
MsgBox.MsgBox_FatalErrorHeader = AppResx.GetString("FATAL_ERROR_HEADER");
MsgBox.MsgBox_FatalErrorFooter = AppResx.GetStringFormated("FATAL_ERROR_APPLICATION_WILL_EXIT", APPLICATION_NAME_LONG) +
AppResx.GetStringFormated("CONTACT_SUPPORT_URGENTLY", SUPPORT_PHONENUMBER) +
AppResx.GetStringFormated("ERROR_LOG_FILE_LOCATION", APP_LOG_FILENAME, APP_LOG_PATH);
// Errors
MsgBox.MsgBox_ErrorTitleHeader = AppResx.GetStringFormated("APPLICATION_ERROR", APPLICATION_NAME_SHORT);
MsgBox.MsgBox_ErrorHeader = AppResx.GetString("ERROR_HEADER");
MsgBox.MsgBox_ErrorFooter = AppResx.GetStringFormated("CONTACT_SUPPORT_NICELY", SUPPORT_PHONENUMBER) +
AppResx.GetStringFormated("ERROR_LOG_FILE_LOCATION", APP_LOG_FILENAME, APP_LOG_PATH);
// Info
MsgBox.MsgBox_InfoTitleHeader = AppResx.GetStringFormated("APPLICATION_INFO", APPLICATION_NAME_SHORT);
// * For Debugging *
//MsgBox.ShowError("01234567890123456789012345678901234567890123456789012345678901234");
//MsgBox.ShowFatalError("01234567890123456789012345678901234567890123456789012345678901234");
}
#endregion
#region Application State
/// <summary>
/// Various Keys that we can use to save/get the GUI State
/// </summary>
internal enum StateKey
{
Monitor_Started_bool,
Monitor_ErrorsOccured_bool,
Scheduler_Started_bool,
SchedulerBackup_Started_bool,
SpecialMode_Paused_Mode_bool,
SpecialMode_CommandLine_Mode_bool,
SpecialMode_RunAsService_Mode_bool,
SpecialCircum_CommandLine_ConsoleWindowIsAttached_bool,
SpecialCircum_CommandLine_MonitorInstanceExists_bool,
SpecialCircum_DontCloseApplicationsOnExit_bool,
Help_Is_Available_bool,
}
/// <summary>
/// State of the System
/// </summary>
public enum StateSystem
{
Running,
Paused,
Stopped,
Error
}
// Initialize BkgdState
internal static readonly StateM State = new StateM(typeof(StateKey));
#endregion
#region Application State - Monitor State
/// <summary>
/// Returns the state of the System (icon to display)
/// </summary>
/// <returns>Application State for System</returns>
internal static StateSystem State_GetSystemState()
{
if (State.GetStateValue<bool>(App.StateKey.Monitor_Started_bool, false))
{
// Error and Pause are Special 'Running' States
if (State.GetStateValue<bool>(App.StateKey.SpecialMode_Paused_Mode_bool, false))
return StateSystem.Paused;
if (State.GetStateValue<bool>(App.StateKey.Monitor_ErrorsOccured_bool, false))
return StateSystem.Error;
else
return StateSystem.Running;
}
else
{
return StateSystem.Stopped;
}
}
/// <summary>
/// Is the Monitor Currently in a 'Running' State
/// </summary>
/// <returns>true if yes, false otherwise</returns>
internal static bool State_MonitorIsInRunningState() { return State.GetStateValue<bool>(App.StateKey.Monitor_Started_bool, false); }
/// <summary>
/// Sets the System into an Error State
/// </summary>
/// <param name="strCustomErrorMessageToNotify">Error Message to Notify to User</param>
internal static void State_Error_SetErrorState(string strErrorMessageToNotify)
{
App.State.SetStateValue<bool>(App.StateKey.Monitor_ErrorsOccured_bool, true);
if (!String.IsNullOrEmpty(strErrorMessageToNotify))
{
////
// Application entered an Error State * Better Notify User, if specified *
////
if (App.setting.EmailNotificationEnabled && App.setting.EmailSettingsValid)
{
bool bIsSend = Emailer.SendEmail(App.setting.EmailStmpServer, App.setting.EmailSenderEmail, App.APPLICATION_NAME_SHORT,
App.setting.EmailReceiverEmail, AppResx.GetStringFormated("ERRORSTATE_EMAIL_SUBJECT", App.APPLICATION_NAME_SHORT),
AppResx.GetStringFormated("ERRORSTATE_EMAIL_BODY", App.APPLICATION_NAME_SHORT, strErrorMessageToNotify ,App.setting.EmailCustomMessageText),
App.setting.EmailSmtpPort, String.Empty, App.setting.EmailStmpServerRequiresAuth, App.setting.EmailSmtpUsername, App.setting.EmailSmtpPassword,
App.setting.EmailStmpServerRequiresSSL, 30);
if (!bIsSend)
App.log.Error("Failed to Send ERRORSTATE_EMAIL");
else
App.log.Info(String.Format("Email (ERRORSTATE_EMAIL) Notification send to {0}", App.setting.EmailReceiverEmail));
}
}
}
/// <summary>
/// Error State Reset
/// </summary>
internal static void State_Error_ResetErrorState() { App.State.SetStateValue<bool>(App.StateKey.Monitor_ErrorsOccured_bool, false); }
/// <summary>
/// Set Main Monitor to Started
/// </summary>
internal static void State_MonitorStarted() { App.State.SetStateValue<bool>(App.StateKey.Monitor_Started_bool, true); App.State.SetStateValue<bool>(App.StateKey.SpecialMode_Paused_Mode_bool, false); }
/// <summary>
/// Set Main Monitor to Stopped
/// </summary>
internal static void State_MonitorStopped() { App.State.SetStateValue<bool>(App.StateKey.Monitor_Started_bool, false); App.State.SetStateValue<bool>(App.StateKey.SpecialMode_Paused_Mode_bool, false); }
/// <summary>
/// Set Main Monitor to Paused
/// </summary>
internal static void State_MonitorPaused() { App.State.SetStateValue<bool>(App.StateKey.SpecialMode_Paused_Mode_bool, true); }
/// <summary>
/// Is the System in a Paused State?
/// </summary>
/// <returns>true if yes, false if no</returns>
internal static bool State_IsMonitorPaused() { return App.State.GetStateValue<bool>(App.StateKey.SpecialMode_Paused_Mode_bool, false); }
#endregion
#region Application State - Scheduler State
/// <summary>
/// Is the Scheduler Executing?
/// </summary>
/// <returns>true if yes, false if no</returns>
internal static bool State_IsSchedulerExecuting() { return App.State.GetStateValue<bool>(App.StateKey.Scheduler_Started_bool, false); }
/// <summary>
/// Scheduler Execution Started
/// </summary>
internal static void State_SchedulerExecution_Started() { App.State.SetStateValue<bool>(App.StateKey.Scheduler_Started_bool, true); }
/// <summary>
/// Scheduler Execution Stopped
/// </summary>
internal static void State_SchedulerExecution_Stopped() { App.State.SetStateValue<bool>(App.StateKey.Scheduler_Started_bool, false); }
/// <summary>
/// Is the Scheduler Executing?
/// </summary>
/// <returns>true if yes, false if no</returns>
internal static bool State_IsSchedulerBackupExecuting() { return App.State.GetStateValue<bool>(App.StateKey.SchedulerBackup_Started_bool, false); }
/// <summary>
/// Scheduler Execution Started
/// </summary>
internal static void State_SchedulerBackupExecution_Started() { App.State.SetStateValue<bool>(App.StateKey.SchedulerBackup_Started_bool, true); }
/// <summary>
/// Scheduler Execution Stopped
/// </summary>
internal static void State_SchedulerBackupExecution_Stopped() { App.State.SetStateValue<bool>(App.StateKey.SchedulerBackup_Started_bool, false); }
#endregion
#region Application State - CommandLine State
/// <summary>
/// Set Application into CommandLine Mode
/// </summary>
internal static void State_SpecialMode_CommandLineSet() { App.State.SetStateValue<bool>(App.StateKey.SpecialMode_CommandLine_Mode_bool, true); }
/// <summary>
/// Is Application in CommandLine Mode?
/// </summary>
/// <returns>true if yes, false if no</returns>
internal static bool State_SpecialMode_IsCommandLineSet() { return App.State.GetStateValue<bool>(App.StateKey.SpecialMode_CommandLine_Mode_bool, false); }
/// <summary>
/// Set Application into RunAsService Mode
/// </summary>
internal static void State_SpecialMode_RunAsServiceSet() { App.State.SetStateValue<bool>(App.StateKey.SpecialMode_RunAsService_Mode_bool, true); }
/// <summary>
/// Is Application in RunAsService Mode?
/// </summary>
/// <returns>true if yes, false if no</returns>
internal static bool State_SpecialMode_IsRunAsServiceSet() { return App.State.GetStateValue<bool>(App.StateKey.SpecialMode_RunAsService_Mode_bool, false); }
/// <summary>
/// Special Circumstance - Set Console as Attached
/// </summary>
internal static void State_SpecialCircum_ConsoleWindowIsAttached() { App.State.SetStateValue<bool>(App.StateKey.SpecialCircum_CommandLine_ConsoleWindowIsAttached_bool, true); }
/// <summary>
/// Special Circumstance - Was Console Window Attached?
/// </summary>
internal static bool State_SpecialCircum_IsConsoleWindowIsAttached() { return App.State.GetStateValue<bool>(App.StateKey.SpecialCircum_CommandLine_ConsoleWindowIsAttached_bool, false); }
/// <summary>
/// Special Circumstance - Set Communication with Main Instance via WCF as Succeeded
/// </summary>
internal static void State_SpecialCircum_MainMonitorInstance_CommSuccees() { App.State.SetStateValue<bool>(App.StateKey.SpecialCircum_CommandLine_MonitorInstanceExists_bool, true); }
/// <summary>
/// Special Circumstance - Did Communication with Mai Instance via WCF Succeed?
/// </summary>
/// <returns>true if yes, false if no</returns>
internal static bool State_SpecialCircum_DidMainMonitorInstanceCommSucceed() { return App.State.GetStateValue<bool>(App.StateKey.SpecialCircum_CommandLine_MonitorInstanceExists_bool, false); }
#endregion
#region Applicaton State - Special States
/// <summary>
/// Special Circumstance - Set that the Application won't close Applications on Exit * Useful for Auto-Updating the Software *
/// </summary>
internal static void State_SpecialCircum_DontCloseApplicationsOnExit() { App.State.SetStateValue<bool>(App.StateKey.SpecialCircum_DontCloseApplicationsOnExit_bool, true); }
/// <summary>
/// Special Circumstance - Check to see if we should Close Applications when Exiting
/// </summary>
/// <returns>true if yes, don't close, false if no</returns>
internal static bool State_SpecialCircum_ShouldWeNotCloseApplicationsOnExit() { return App.State.GetStateValue<bool>(App.StateKey.SpecialCircum_DontCloseApplicationsOnExit_bool, false); }
/// <summary>
/// Check to see if html is available
/// </summary>
/// <returns>true, if available, false otherwise</returns>
internal static bool State_HtmlHelpIsAvailable() { return App.State.GetStateValue<bool>(App.StateKey.Help_Is_Available_bool, false); }
/// <summary>
/// Set Html Help File as available
/// </summary>
internal static void State_HtmlHelpAvailable() { App.State.SetStateValue<bool>(App.StateKey.Help_Is_Available_bool, true); }
#endregion
#region Unhandled Expections! IMP - Show WinForm and Log
/// <summary>
/// * Generic Unhandled Exception Handler *
/// Handles all unhandled Exceptions for the Entire AppDomain.
/// First Show a Window Message Box, so that we can for sure capture the message
/// Second Log it
/// </summary>
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.ExceptionObject;
// Exeption to capture error information
string exceptionMessage = AppResx.GetString("FATAL_ERROR_HEADER");
exceptionMessage = AppResx.GetStringFormated("FATAL_ERROR_APPLICATION_WILL_EXIT", APPLICATION_NAME_LONG);
exceptionMessage += ex.Message + "\n\n";
if (!String.IsNullOrEmpty(ex.StackTrace))
exceptionMessage += ex.StackTrace.Substring(0, 880) + "\n\n";
if(!String.IsNullOrEmpty(ex.InnerException.Message))
exceptionMessage += ex.InnerException.Message + "\n\n";
if (!String.IsNullOrEmpty(ex.Source))
exceptionMessage += ex.Source + "\n\n";
// Polite Message to Show in Message Box
string PoliteExceptionMessage = exceptionMessage +
AppResx.GetStringFormated("CONTACT_SUPPORT_URGENTLY", SUPPORT_PHONENUMBER) +
AppResx.GetStringFormated("ERROR_LOG_FILE_LOCATION", APP_LOG_FILENAME, APP_LOG_PATH);
// Show Message Box First - Guaranteed to work (Polite Exception Message)
MessageBox.Show(PoliteExceptionMessage, AppResx.GetStringFormated("APPLICATION_FATAL_ERROR", APPLICATION_NAME_SHORT), MessageBoxButton.OK, MessageBoxImage.Error);
// Log the Error to the Main Log File
CreateAppMainLogging().Fatal(exceptionMessage, ex);
}
#endregion
#region Fatal Exception! IMP - Show WinForm, Log, and Exit the Application
/// <summary>
/// Some Events continue execution, even though a fatal exception occured (.net!)
/// This flag allows those functions to check for this and stop processing
/// </summary>
public static bool s_FatalErrorOccured = false;
/// <summary>
/// Custom User Specified Fatal Exception Occured * Stops Application Execution *
/// </summary>
/// <param name="Message">Message to show/log</param>
//public static void FatalExceptionStopExecution(string Message, bool bShowMessageBox = true)
public static void FatalExceptionStopExecution(string Message, bool bShowMessageBox)
{
s_FatalErrorOccured = true;
log.Fatal(Message);
if(bShowMessageBox && !App.State_SpecialMode_IsRunAsServiceSet())
MsgBox.ShowFatalError(Message, "", Forms.MessageBoxButtons.OK);
App.Current.Shutdown();
// To make 100% sure, that we are exiting... (not needed)
//System.Diagnostics.Process.GetCurrentProcess().Kill();
}
#endregion
#region Application Multi-File Assembly Handling
/// <summary>
/// A way to embed multiple dlls into one exe:
/// http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
/// </summary>
/// <returns>a loaded assembly if found, null otherwise</returns>
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string curAssemblyName = AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Executing);
String resourceName = curAssemblyName + ".Components." + new AssemblyName(args.Name).Name + ".dll";
//string[] resources = AssemblyW.SpecializedAssemblyInfo.GetAssemblyResourceNames(AssemblyW.AssemblyST.Entry);
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
if(stream != null)
{
using (stream)
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
return null;
}
#endregion
#region Application Startup N' Exit
/// <summary>
/// Handles the Application StartUp event
/// </summary>
private void Application_Startup(object sender, StartupEventArgs e)
{
// We need to make sure that the Permissions are set correctly for
// the ProgramData/AllUser folder for ALL our configuration files
Installer.GrantFullPermissionToFolderForUserOrGroup(APP_XML_DS_PATH, "Everyone");
// Create the First Main Log Instance
log = CreateAppMainLogging();
// Parse the Command Line
cmdline.Parse(e.Args);
// Delay Start * Imp. for Auto-Update Feature
string[] activationData = null;
if(AppDomain.CurrentDomain.SetupInformation.ActivationArguments != null)
activationData = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData;
if (activationData != null && activationData.Length > 0)
{
uint uDelayStart = 0;
if (uint.TryParse(activationData[0], out uDelayStart) && (uDelayStart > 0))
{
App.log.Info(String.Format("Auto Update Delay Start Called with {0} Seconds", uDelayStart));
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(uDelayStart));
}
}
// If Command-Line has params, we are being launched in Command-Line Mode * Hence, we put
// the app into a different State *
if (cmdline.HasParams && !cmdline.GetFlagValue(CommandLine_Flag.RUNASSERVICE)) // RunAsService is NOT Command-line Mode
{
App.State_SpecialMode_CommandLineSet();
log.Info(AppResx.GetStringFormated("APPLICATION_STARTED_COMMANDLINE_MODE", APPLICATION_NAME_SHORT, cmdline.ParsedArgs(), APPLICATION_VERSION));
}
else if (cmdline.HasParams && cmdline.GetFlagValue(CommandLine_Flag.RUNASSERVICE)) // RunAsService is it's own Mode
{
State_SpecialMode_RunAsServiceSet();
log.Info(AppResx.GetStringFormated("APPLICATION_STARTED_SERVICE_MODE", APPLICATION_NAME_SHORT, cmdline.ParsedArgs(), APPLICATION_VERSION));
}
else
{
log.Info(AppResx.GetStringFormated("APPLICATION_STARTED", APPLICATION_NAME_SHORT, APPLICATION_VERSION));
}
// Configure our Message Boxes
ConfigureAppMainMsgBox();
// Create the Xml File Instance * To Read/Write DataStore *
// ~Also, don't allow the configuration to add this Application to the Configuration
DelegateCollection.Void_Param1_Exception_Func XmlFileExceptionHandler = delegate(Exception ex)
{
App.log.Error("Saving MonitorDataStore XMLFile Error Thrown", ex);
if(!App.State_SpecialMode_IsRunAsServiceSet())
MsgBox.ShowError("Saving XMLDataStore XMLFile Error " + ex.Message, "", Forms.MessageBoxButtons.OK);
};
List<string> excludedProcessNames = new List<String>();
excludedProcessNames.Add(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileName(AssemblyW.AssemblyST.Entry));
xmlfile = new MonitorDataStore(App.APP_XML_DS_FILENAMEANDPATH, excludedProcessNames, XmlFileExceptionHandler);
// If this is a Debug build, enable * Performance Tracing *
#if DEBUG
TraceM.EnableTracing = true;
#endif
// Make sure that the File Name of this Assembly matches the Assembly Name,
// this allows us to enforce for sure that only One Instance of this program is running
// i.e. someone could run this program otherwise by just changing the filename
string entryAssemblyName = AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Entry);
string entryAssemblyFileName = AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileName(AssemblyW.AssemblyST.Entry);
if (String.Compare(entryAssemblyName, entryAssemblyFileName, true) != 0)
FatalExceptionStopExecution(AppResx.GetStringFormated("FATAL_ERROR_ASSEMBLY_FILENAME_MISMATCH", entryAssemblyName, entryAssemblyFileName), true);
// Check that this is the ONLY Instance running on this Machine
// ~We only allow one instance of this app to be running... (Only Do this if NOT in Command-Line Mode)
if (!s_FatalErrorOccured && !App.State_SpecialMode_IsCommandLineSet())
{
// Check if there are other instances. Start/Stop/Etc won't work if other instances are not running
bool bAnotherInstanceIsRunning = true;
#if DEBUG
bAnotherInstanceIsRunning = !ProcessW.IsTheOnlyProcessRunning(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileName(AssemblyW.AssemblyST.Entry).ToLower(), false);
#else
bAnotherInstanceIsRunning = !ProcessW.IsTheOnlyProcessRunning(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileName(AssemblyW.AssemblyST.Entry).ToLower(), true);
#endif
if (bAnotherInstanceIsRunning)
{
// Alert the User and ask the User, if they would like to close that process,
// * Could be that The Application Errored out, yet still remains running, so they are trying to restart it *
Process[] ps = null;
#if DEBUG
ps = ProcessW.AllRunningProcessesOf(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileName(AssemblyW.AssemblyST.Entry).ToLower(), false, true);
#else
ps = ProcessW.AllRunningProcessesOf(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileName(AssemblyW.AssemblyST.Entry).ToLower(), true, true);
#endif
Forms.DialogResult dr = System.Windows.Forms.DialogResult.Ignore;
if (!App.State_SpecialMode_IsRunAsServiceSet())
{
string msg = AppResx.GetStringFormated("FATAL_ERROR_OTHER_INSTANCES", App.APPLICATION_NAME_SHORT);
msg += "\nWould you like to try to force close the other instance(s)?\n";
msg += "\nClicking 'Yes' will force all other instances to close.";
msg += "\nClicking 'No' will close this instance.";
dr = MsgBox.ShowInfo(msg, "Other Instance Found", Forms.MessageBoxButtons.YesNo);
}
// Check Dialog Result (If in GUI MODE)
if (dr == Forms.DialogResult.Yes)
{
// try to kill all other instances
bool bSuccess = true;
foreach (Process p in ps)
{
if(Process.GetCurrentProcess().Id != p.Id)
bSuccess = PStarter.KillProcess((uint)p.Id, false, 1, true, 2);
if (!bSuccess)
break;
}
if (!bSuccess)
{
App.log.Error("Error occured closing other instances");
FatalExceptionStopExecution(AppResx.GetStringFormated("FATAL_ERROR_OTHER_INSTANCES", App.APPLICATION_NAME_SHORT), false);
}
else
{
// * Opportunity To Start the WCF Host *
WCFHost.StartHost();
// Refresh the taskbar, after killing any instances
Watchdog.WatchdogLib.Win32.Functions.RefreshTaskbarNotificationArea();
}
}
else
{
FatalExceptionStopExecution(AppResx.GetStringFormated("FATAL_ERROR_OTHER_INSTANCES", App.APPLICATION_NAME_SHORT), false);
}
}
else
{
// * Opportunity To Start the WCF Host *
WCFHost.StartHost();
// * Opportunity to load the chm help file *
// ~Force a new chm file write, if an upgrade occured
try
{
#if DEBUG
bool bForceCreationOfNewCHMFile = true;
#else
bool bForceCreationOfNewCHMFile = (App.APPLICATION_VERSION != App.setting.LastProgramVersion);
#endif
string curAssemblyName = AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Executing);
App.chmhelp = new CHMFile(Assembly.GetExecutingAssembly().GetManifestResourceStream(curAssemblyName + "." + "Watchdog.chm"), App.APPLICATION_NAME_SHORT, bForceCreationOfNewCHMFile);
if (App.chmhelp != null)
App.State_HtmlHelpAvailable(); // Html Help loaded successfully
if (bForceCreationOfNewCHMFile && (App.chmhelp != null))
App.setting.LastProgramVersion = App.APPLICATION_VERSION;
}
catch (Exception ex)
{
App.log.Error("Failed to create chm Helf File", ex);
}
}
}
else if (!s_FatalErrorOccured && App.State_SpecialMode_IsCommandLineSet())
{
// We are called with CmdLine Parameters * Try Attaching to the console, in case we got called from a Command Window *
bool bAttachSuccess = Watchdog.WatchdogLib.Win32.Kernel32.AttachConsole(-1);
App.log.Info(String.Format("CommandLineMode - Attached to Console is {0}", bAttachSuccess));
if (bAttachSuccess)
App.State_SpecialCircum_ConsoleWindowIsAttached();
}
}
/// <summary>
/// Handles the Application Exit event.
/// </summary>
private void Application_Exit(object sender, ExitEventArgs e)
{
if (!App.State_SpecialMode_IsCommandLineSet())
{
log.Info(AppResx.GetStringFormated("APPLICATION_ENDED", APPLICATION_NAME_SHORT, APPLICATION_VERSION));
// * Opportunity To Stop the WCF Host *
WCFHost.StopHost();
}
else if(App.State_SpecialMode_IsCommandLineSet())
{
if(App.State_SpecialCircum_IsConsoleWindowIsAttached())
{
bool bFreeSuccess = Watchdog.WatchdogLib.Win32.Kernel32.FreeConsole();
App.log.Info(String.Format("CommandLineMode - Free from Console is {0}", bFreeSuccess));
}
log.Info(AppResx.GetStringFormated("APPLICATION_ENDED_COMMANDLINE_MODE", APPLICATION_NAME_SHORT, APPLICATION_VERSION));
}
}
#endregion
}
}

161
@integrate/AppState.cs Normal file
View File

@@ -0,0 +1,161 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Watchdog.WatchdogLib.Other;
namespace Watchdog
{
/// <summary>
/// Keeps Track of RunTime State Variables/Objects
/// </summary>
public static class AppState
{
private static object s_LockObject = new Object();
#region Internal State Check Functions
/// <returns>true if the Process Monitor is running, false otherwise</returns>
internal static bool IsMonitorRunning()
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.ProcessMonitorStarted_bool, false);
}
}
/// <returns>true if the Scheduler is running, false otherwise</returns>
internal static bool IsSchedulerRunning()
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.SchedulerIsRunning_bool, false);
}
}
/// <returns>true if the Process Monitor encountered errors, false otherwise</returns>
internal static bool DidMonitorEncounterErrors()
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.ProcessMonitorEncounteredErrors_bool, false);
}
}
/// <returns>true if the Application is called with Command-Line Parameters, false otherwise</returns>
internal static bool IsInCommandLinePrmsMode()
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.IsInCommandLineMode_bool, false);
}
}
/// <returns>true if the Application is attached to a Console Window For Output, false otherwise</returns>
internal static bool IsAttachedToConsoleWindow()
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.IsAttachedToConsoleWindow_bool, false);
}
}
/// <returns>When the application is in commandline mode, we want to make sure that a 'real' monitor instance is running,
/// in order to communicate with it, this keeps track if that other instance is available</returns>
internal static bool InCommandLineMode_IsMonitorInstanceAvailable()
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.InCommandLineMode_IsMonitorInstanceAvailable_bool, false);
}
}
#endregion
#region Internal State Set Functions
/// <summary>
/// Use this to set the Monitor is Running state to true/false
/// </summary>
internal static bool MonitorIsRunning(bool bIsRunning)
{
lock (s_LockObject)
{
return AppState.State.SetStateValue<bool>(AppState.StateKey.ProcessMonitorStarted_bool, bIsRunning);
}
}
/// <summary>
/// Use this to set the Scheduler is Running state to true/false
/// </summary>
internal static bool SchedulerIsRunning(bool bIsRunning)
{
lock (s_LockObject)
{
return AppState.State.SetStateValue<bool>(AppState.StateKey.SchedulerIsRunning_bool, bIsRunning);
}
}
/// <summary>
/// Use this to set the Monitor's Error State
/// </summary>
internal static bool MonitorEncounterErrors(bool bErrorsOccured)
{
lock (s_LockObject)
{
return AppState.State.SetStateValue<bool>(AppState.StateKey.ProcessMonitorEncounteredErrors_bool, bErrorsOccured);
}
}
/// <summary>
/// Use this to set that the Application is called with Command-Line Parameters
/// </summary>
internal static bool CommandLinePrmsMode(bool bIsInCommandLinePrmsMode)
{
lock (s_LockObject)
{
return AppState.State.SetStateValue<bool>(AppState.StateKey.IsInCommandLineMode_bool, bIsInCommandLinePrmsMode);
}
}
/// <summary>
/// Use this to set that the Application is attached to a Console Window for Output
/// </summary>
internal static bool AttachedToConsoleWindow(bool bItIsAttached)
{
lock (s_LockObject)
{
return AppState.State.SetStateValue<bool>(AppState.StateKey.IsAttachedToConsoleWindow_bool, bItIsAttached);
}
}
/// <summary>
/// Use this to set that the Application can communicate with the 'real' monitor instance that is running.
/// </summary>
internal static bool CommandLineMode_IsMonitorInstanceAvailable(bool bIsAvailable)
{
lock (s_LockObject)
{
return AppState.State.GetStateValue<bool>(AppState.StateKey.InCommandLineMode_IsMonitorInstanceAvailable_bool, bIsAvailable);
}
}
#endregion
/// <summary>
/// Various Keys that we can use to save/get the GUI State
/// </summary>
internal enum StateKey
{
ProcessMonitorStarted_bool,
ProcessMonitorEncounteredErrors_bool,
SchedulerIsRunning_bool,
IsInCommandLineMode_bool,
IsAttachedToConsoleWindow_bool,
InCommandLineMode_IsMonitorInstanceAvailable_bool,
}
// Initialize BkgdState
internal static readonly StateM State = new StateM(typeof(StateKey));
}
}

View File

@@ -0,0 +1,311 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using WatchdogLib;
using Watchdog.WatchdogLib.WinForms;
using Watchdog.WatchdogLib.Win32;
namespace Watchdog
{
/// <summary>
/// Handles CommandLine Logic
/// </summary>
public static class CMDlineHandler
{
// Our WCF Client object stub
private static IWatchdog _proxyObj = null;
/// <summary>
/// Shows the Command Line Help either as a Windows Form or
/// to the Console * Depending if a Console Window is Attached *
/// </summary>
private static void ShowCommandLineHelp()
{
bool bToConsole = App.State_SpecialCircum_IsConsoleWindowIsAttached();
string cmdHelpText = "";
cmdHelpText += "\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += " Make changes to the .xml Configuration.\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += "-Add_Process \"Application Exe;Prms;WorkingDir\"\n";
cmdHelpText += "-Remove_Process \"Application Exe;Prms\"\n";
cmdHelpText += "-Add_Service \"Service Name\"\n";
cmdHelpText += "-Remove_Service \"Service Name\"\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += " View the .xml Configuration.\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += "-Show_Processes\n";
cmdHelpText += "-Show_Services\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += " Manipulate a Running Monitor Instance.\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += "-Start\n";
cmdHelpText += "-Pause\n";
cmdHelpText += "-Restart\n";
cmdHelpText += "-Restart_All\n";
cmdHelpText += "-Stop\n";
cmdHelpText += "-Stop_All\n";
cmdHelpText += "**************************************************************\n";
cmdHelpText += "-? Show Help.\n\n";
// Show Help to the User (Either to the console or a Message Window)
if (bToConsole)
Console.Write(cmdHelpText);
else
MsgBox.ShowInfo(cmdHelpText, (App.APPLICATION_NAME_SHORT + " Command Line Help"), System.Windows.Forms.MessageBoxButtons.OK);
}
/// <summary>
/// Either writes out to the console or shows a message box, if we want to alert the user
/// </summary>
/// <param name="str">string to write out</param>
private static void WriteOut(string str)
{
bool bToConsole = App.State_SpecialCircum_IsConsoleWindowIsAttached();
if (bToConsole)
Console.WriteLine("\n" + str);
else
MsgBox.ShowInfo(str, (App.APPLICATION_NAME_SHORT + " Command Line Alert"), System.Windows.Forms.MessageBoxButtons.OK);
}
/// <summary>
/// Main Entry Point for CommandLine Mode * When Application is being called with
/// CommandLine Parameters *
/// </summary>
static public void EnterCommandLineMode()
{
// Show Help?
if (App.cmdline.ShowHelp || !App.cmdline.ParamsValid)
{
ShowCommandLineHelp();
return;
}
// Check now using WCF...
// Now we need to check communication with the other instance,
// if there isn't another process, then start/stop/restart/etc,.. won't work
_proxyObj = WCFHost.GetWatchDogClientInterface();
if (_proxyObj != null)
App.State_SpecialCircum_MainMonitorInstance_CommSuccees();
else
App.log.Info("No other Instances found, Command-line parameter functionallity limited to making configuration changes only");
// Now let's go thru all the CommandLine_Flags * WCF *
DealWithApplicationStateWCFCalls_CommandLineFlags();
// Now let's go thru all the CommandLine_Flags * Non-WCF *
DealWithDisplayConfigurationNonWCFCalls_CommandLineFlags();
// Now let's go thru all the CommandLine_Options * Non-WCF *
DealWithConfigurationChanges_CommandLineOptions();
// Done Here
_proxyObj = null;
}
/// <summary>
/// Deals with all the State Changes for the Main Application
/// * Via WCF * calls into main app and makes those changes
/// </summary>
private static void DealWithApplicationStateWCFCalls_CommandLineFlags()
{
// Now let's go thru all the CommandLine_Flags * WCF *
if (App.State_SpecialCircum_DidMainMonitorInstanceCommSucceed())
{
try
{
if (App.cmdline.GetFlagValue(App.CommandLine_Flag.START))
{
_proxyObj.StartMonitoring();
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.STOP))
{
_proxyObj.StopMonitoring();
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.STOP_ALL))
{
_proxyObj.StopAllMonitoring();
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.RESTART))
{
_proxyObj.RestartMonitoring();
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.RESTART_ALL))
{
_proxyObj.RestartAllMonitoring();
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.PAUSE))
{
_proxyObj.PauseMonitoring();
}
}
catch (Exception ex)
{
App.log.Error("Error Occured processing CommandLine_Flag via WCF", ex);
// Alert the user
WriteOut(ex.Message);
}
}
}
/// <summary>
/// Deals with all the Flags that deal with displaying configuration. does this locally * in this process *
/// View Configuration. Also handles LockWorkstation (Feature).
/// </summary>
private static void DealWithDisplayConfigurationNonWCFCalls_CommandLineFlags()
{
if (App.cmdline.GetFlagValue(App.CommandLine_Flag.LOCK))
{
// Hidden Feature, allows us to specify in windows start-up to lock the workstation
if (!User32.LockWorkStation())
{
App.log.Error("LockWorkstation() Failed");
WriteOut("LockWorkstation Failed");
}
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.SHOW_PROCESSES))
{
// write out each process
string[] processes = WCFHost.ShowProcesses();
StringBuilder sb = new StringBuilder();
if (processes != null && processes.Length != 0)
{
foreach (string p in processes)
{
sb.Append(p);
sb.Append("\n");
}
}
if (sb.Length > 0)
WriteOut(sb.ToString());
}
else if (App.cmdline.GetFlagValue(App.CommandLine_Flag.SHOW_SERVICES))
{
// write out each service
string[] services = WCFHost.ShowServices();
StringBuilder sb = new StringBuilder();
if (services != null && services.Length != 0)
{
foreach (string s in services)
{
sb.Append(s);
sb.Append("\n");
}
}
if (sb.Length > 0)
WriteOut(sb.ToString());
}
}
/// <summary>
/// Deals with making configuration changes. does this locally * in this process *
/// Add/Remove Configuration
/// </summary>
private static void DealWithConfigurationChanges_CommandLineOptions()
{
string ProcessAdd = App.cmdline.GetOptionValue<string>(App.CommandLine_Option.ADD_PROCESS, String.Empty);
if (String.IsNullOrEmpty(ProcessAdd))
{
string ProcessRemove = App.cmdline.GetOptionValue<string>(App.CommandLine_Option.REMOVE_PROCESS, String.Empty);
if (String.IsNullOrEmpty(ProcessRemove))
{
string ServiceAdd = App.cmdline.GetOptionValue<string>(App.CommandLine_Option.ADD_SERVICE, String.Empty);
if (String.IsNullOrEmpty(ServiceAdd))
{
string ServiceRemove = App.cmdline.GetOptionValue<string>(App.CommandLine_Option.REMOVE_SERVICE, String.Empty);
if (!String.IsNullOrEmpty(ServiceRemove))
{
bool bRemoved = WCFHost.RemoveService(ServiceRemove);
if (bRemoved)
{
WriteOut(String.Format("Service '{0}' removed successfully from Configuration", ServiceRemove));
App.log.Info(String.Format("Service '{0}' removed successfully from Configuration", ServiceRemove));
// * Reload on Main Instance, if possible *
if (App.State_SpecialCircum_DidMainMonitorInstanceCommSucceed()) _proxyObj.ReloadConfigurationNextInterval();
App.xmlfile.ForceRefreshOnNext_ReadData = true;
}
else
{
WriteOut(String.Format("Service '{0}' failed to be removed from Configuration", ServiceRemove));
App.log.Error(String.Format("Service '{0}' failed to be removed from Configuration", ServiceRemove));
}
}
}
else
{
bool bAdded = WCFHost.AddService(ServiceAdd);
if (bAdded)
{
WriteOut(String.Format("Service '{0}' added successfully to Configuration", ServiceAdd));
App.log.Info(String.Format("Service '{0}' added successfully to Configuration", ServiceAdd));
// * Reload on Main Instance, if possible *
if (App.State_SpecialCircum_DidMainMonitorInstanceCommSucceed()) _proxyObj.ReloadConfigurationNextInterval();
App.xmlfile.ForceRefreshOnNext_ReadData = true;
}
else
{
WriteOut(String.Format("Service '{0}' failed to be added to Configuration", ServiceAdd));
App.log.Error(String.Format("Service '{0}' failed to be added to Configuration", ServiceAdd));
}
}
}
else
{
string[] pNc = ProcessRemove.Split(';');
bool bRemoved = false;
if (pNc.Length == 1)
bRemoved = WCFHost.RemoveProcess(pNc[0], String.Empty);
else if (pNc.Length == 2)
bRemoved = WCFHost.RemoveProcess(pNc[0], pNc[1]);
if (bRemoved)
{
WriteOut(String.Format("Application '{0}' with CommandLinePrms '{1}' removed successfully from Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
App.log.Info(String.Format("Application '{0}' with CommandLinePrms '{1}' removed successfully from Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
// * Reload on Main Instance, if possible *
if (App.State_SpecialCircum_DidMainMonitorInstanceCommSucceed()) _proxyObj.ReloadConfigurationNextInterval();
App.xmlfile.ForceRefreshOnNext_ReadData = true;
}
else
{
WriteOut(String.Format("Application '{0}' with CommandLinePrms '{1}' failed to be removed from Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
App.log.Error(String.Format("Application '{0}' with CommandLinePrms '{1}' failed to be removed from Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
}
}
}
else
{
string[] pNc = ProcessAdd.Split(';');
bool bAdded = false;
if(pNc.Length == 1)
bAdded = WCFHost.AddProcess(pNc[0], String.Empty, String.Empty);
else if(pNc.Length == 2)
bAdded = WCFHost.AddProcess(pNc[0], pNc[1], String.Empty);
else if (pNc.Length == 3)
bAdded = WCFHost.AddProcess(pNc[0], pNc[1], pNc[2]);
if (bAdded)
{
WriteOut(String.Format("Application '{0}' with CommandLinePrms '{1}' added successfully to Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
App.log.Info(String.Format("Application '{0}' with CommandLinePrms '{1}' added successfully to Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
// * Reload on Main Instance, if possible *
if (App.State_SpecialCircum_DidMainMonitorInstanceCommSucceed()) _proxyObj.ReloadConfigurationNextInterval();
App.xmlfile.ForceRefreshOnNext_ReadData = true;
}
else
{
WriteOut(String.Format("Application '{0}' with CommandLinePrms '{1}' failed to be added to Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
App.log.Error(String.Format("Application '{0}' with CommandLinePrms '{1}' failed to be added to Configuration", pNc[0], (pNc.Length > 1) ? pNc[1] : ""));
}
}
}
}
}

View File

@@ -0,0 +1,482 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Diagnostics;
namespace PhoneHome
{
internal class CheckActiveTwo
{
internal string ProductName = String.Empty;
internal string ProductVersion = String.Empty;
internal string SerialNumber = String.Empty;
private string _LastGeneratedKey = String.Empty;
/// <summary>
///
/// </summary>
/// <param name="ProductName"></param>
/// <param name="ProductVersion"></param>
/// <param name="SerialNumber"></param>
internal CheckActiveTwo(string ProductName, string ProductVersion, string SerialNumber)
{
if (!String.IsNullOrEmpty(ProductName) && !String.IsNullOrEmpty(ProductVersion) && !String.IsNullOrEmpty(SerialNumber))
{
this.ProductName = ProductName;
this.ProductVersion = ProductVersion;
this.SerialNumber = SerialNumber;
}
else
{
throw new ArgumentException("ProductName, ProductVersion, and SerialNumber can't be blank");
}
}
/// <summary>
///
/// </summary>
/// <param name="strEncGeneratedString"></param>
internal CheckActiveTwo(string strEncGeneratedString)
{
if (IsValidEncKey(strEncGeneratedString))
{
_LastGeneratedKey = strEncGeneratedString;
}
else
{
throw new ArgumentException("Not a valid Enc String");
}
}
#region Static Internal Utilities
/// <summary>
/// Perform checksum on string
/// </summary>
/// <param name="strAboutToBeChecksummed"></param>
/// <returns>Checksum</returns>
internal static int PerformChecksum(string strAboutToBeChecksummed)
{
if (!String.IsNullOrEmpty(strAboutToBeChecksummed))
{
int nChecksum = 0;
for (int i = 0; i < strAboutToBeChecksummed.Length; ++i)
{
if (Char.IsDigit(strAboutToBeChecksummed[i]))
nChecksum = nChecksum + int.Parse(strAboutToBeChecksummed[i].ToString());
}
return nChecksum;
}
return 0;
}
/// <summary>
/// Dash a String
/// </summary>
/// <returns></returns>
internal static string MakeIntoDashSeperatedString(string strAboutToBeDashed, int DashEveryNthCharacter)
{
if (!String.IsNullOrEmpty(strAboutToBeDashed))
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < strAboutToBeDashed.Length; i++)
{
if ((i != 0) && ((i % DashEveryNthCharacter) == 0))
sb.Append("-");
sb.Append(strAboutToBeDashed[i]);
}
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Undash a String
/// </summary>
/// <returns></returns>
internal static string MakeIntoDashUnseperatedString(string strAboutToBeUndashed)
{
if (!String.IsNullOrEmpty(strAboutToBeUndashed))
return strAboutToBeUndashed.Replace("-", "");
return String.Empty;
}
#endregion
#region Internal Methods
/// <summary>
/// Generate a new Key to use - the key can be used to verify the serial number
/// </summary>
/// <returns>a new Key</returns>
internal string GenerateNewKey()
{
// GenerateString For User to send
string KeyValue = MakeKey();
string EncrKey = EncodeShuffle(KeyValue);
_LastGeneratedKey = MakeIntoDashSeperatedString(EncrKey, 4);
// For Debugging
string UnEncoded = DecodeShuffle(EncrKey);
if (KeyValue != UnEncoded)
{
// something is terribly wrong with the Encryption
Debug.Assert(false);
}
return _LastGeneratedKey;
}
/// <summary>
/// The function should really be called 'GeneratedPIN' but for reverse engineering
/// purpose, keeping them guessin * security by obscurity *
/// </summary>
/// <returns></returns>
internal string GeneraledPiM()
{
if (!String.IsNullOrEmpty(_LastGeneratedKey))
{
int KeyChecksum = PerformChecksum(MakeKey());
int ShuffledChecksum = PerformChecksum(_LastGeneratedKey);
string Result = KeyChecksum.ToString() + ShuffledChecksum.ToString();
if (Result.Length < 4)
{
StringBuilder sb = new StringBuilder(Result);
int nRemainder = 4 - Result.Length;
while (nRemainder > 0) { sb.Append("7"); nRemainder--; }
Result = sb.ToString();
}
Result = Result.Substring(0, 4);
int nHour = DateTime.Now.ToUniversalTime().Hour;
nHour = (nHour <= 6) ? (nHour + 3) : (nHour - 2);
string strHour = String.Format("{0}", (nHour < 10) ? ("8" + nHour.ToString()) : (nHour.ToString()));
string fourdigitPin = (strHour[1] + Result[1].ToString() + strHour[0] + Result[3].ToString());
int nChecksumPin = PerformChecksum(fourdigitPin);
string strChecksumLastDigit = nChecksumPin.ToString()[nChecksumPin.ToString().Length - 1].ToString();
return fourdigitPin + strChecksumLastDigit;
}
else
{
GenerateNewKey();
return GeneraledPiM();
}
}
/// <summary>
///
/// </summary>
/// <param name="dtStamp"></param>
/// <param name="ProductName"></param>
/// <param name="ProductVersion"></param>
/// <param name="SerialNumber"></param>
/// <returns>true, if successful, false otherwise</returns>
internal bool RetrieveValues(out DateTime dtStamp, out string ProductName, out string ProductVersion, out string SerialNumber)
{
dtStamp = DateTime.MinValue;
ProductName = String.Empty;
ProductVersion = String.Empty;
SerialNumber = String.Empty;
if (!String.IsNullOrEmpty(_LastGeneratedKey))
{
string Undashed = MakeIntoDashUnseperatedString(_LastGeneratedKey);
if (UnmakeKey(DecodeShuffle(Undashed), out dtStamp, out ProductName, out ProductVersion, out SerialNumber))
{
this.ProductName = ProductName;
this.ProductVersion = ProductVersion;
this.SerialNumber = SerialNumber;
return true;
}
}
return false;
}
#endregion
#region Private Key Generation Functions
private bool ContainsOnlyDigits(string strToCheckForDigits)
{
if (!String.IsNullOrEmpty(strToCheckForDigits))
{
for (int i = 0; i < strToCheckForDigits.Length; ++i)
{
if (!Char.IsDigit(strToCheckForDigits[i]))
return false;
}
return true;
}
return false;
}
/// <summary>
/// Check to see if the Generated string being passed in is a valid generated string
/// </summary>
/// <param name="strGeneratedString"></param>
/// <returns>true if valid, false otherwise</returns>
private bool IsValidEncKey(string strEncGeneratedString)
{
string Undashed = MakeIntoDashUnseperatedString(strEncGeneratedString);
DateTime dt;
string pName, pVersion, pSerial;
if (UnmakeKey(DecodeShuffle(Undashed), out dt, out pName, out pVersion, out pSerial))
return true;
return false;
}
/// <summary>
/// Make a Key to send across (all the info the auth needs)
/// </summary>
/// <returns>Key with needed Info</returns>
private string MakeKey()
{
//string dtShortTest = DateTime.Now.ToUniversalTime().ToShortDateString().Replace("/", "");
DateTime dtUniversal = DateTime.Now.ToUniversalTime();
string dtMonth = (dtUniversal.Month > 9) ? String.Format("{0}", dtUniversal.Month) : String.Format("0{0}", dtUniversal.Month);
string dtDay = (dtUniversal.Day > 9) ? String.Format("{0}", dtUniversal.Day) : String.Format("0{0}", dtUniversal.Day);
string dtYear = dtUniversal.Year.ToString();
string dtShort = String.Format("{0}{1}{2}", dtMonth, dtDay, dtYear);
string ProductId = ProductName.Substring(0, 1); // should always be 'M' or 'L' // so we use "LMXYZ"
string strKey = dtShort + "Z" + ProductId + "Y" + ProductVersion.Split('.')[0] + "X" + SerialNumber;
return strKey;
}
/// <summary>
/// Unmake a key * Don't even know why i wrote this, prob. won't end up using this *
/// </summary>
/// <returns>true if successful, false otheriwise</returns>
private bool UnmakeKey(string strAboutToBeUnkeyed, out DateTime dtStamp, out string ProductName, out string ProductVersion, out string SerialNumber)
{
dtStamp = DateTime.MinValue;
ProductName = "";
ProductVersion = "";
SerialNumber = "";
//string strKey = dtShort + "Z" + ProductId + "Y" + ProductVersion.Split('.')[0] + "X" + SerialNumber;
//0123456Z
try
{
if (!String.IsNullOrEmpty(strAboutToBeUnkeyed))
{
int nZIndex = strAboutToBeUnkeyed.IndexOf("Z");
int nYIndex = strAboutToBeUnkeyed.IndexOf("Y");
int nXIndex = strAboutToBeUnkeyed.IndexOf("X");
if (nZIndex == -1 || nYIndex == -1 || nXIndex == -1)
return false;
// dtShort
string strDT = strAboutToBeUnkeyed.Substring(0, nZIndex);
strDT = String.Format("{0}/{1}/{2}", strDT.Substring(0, 2), strDT.Substring(2, 2), strDT.Substring(4));
dtStamp = DateTime.Parse(strDT);
// ProductId
string ProductId = strAboutToBeUnkeyed.Substring(nZIndex + 1, 1);
if (ProductId == "L")
ProductName = "Lytec";
else if (ProductId == "M")
ProductName = "Medisoft";
else
return false;
// ProductVersion
string strProductVersion = strAboutToBeUnkeyed.Substring(nYIndex + 1, (nXIndex - nYIndex - 1));
if (!String.IsNullOrEmpty(strProductVersion) && ContainsOnlyDigits(strProductVersion))
ProductVersion = strProductVersion;
else
return false;
// Serial Number
SerialNumber = strAboutToBeUnkeyed.Substring(nXIndex + 1);
return !String.IsNullOrEmpty(SerialNumber) && ContainsOnlyDigits(SerialNumber);
}
}
catch (Exception) { /* ignore */ }
return false;
}
/// <summary>
/// * Simple Encoder *
/// </summary>
/// <param name="strAboutToBeEncodeShuffled"></param>
/// <returns></returns>
private string EncodeShuffle(string strAboutToBeEncodeShuffled)
{
const string Char_CodeLib = "ABCDEFGHIJKNOPQRSTUVW"; //20 - W is never used
const string Char_CodeLibExcluded = "LMXYZ"; //5
if (!String.IsNullOrEmpty(strAboutToBeEncodeShuffled))
{
List<char> ResultStr = new List<char>(strAboutToBeEncodeShuffled);
int nCount = ResultStr.Count;
// Every N'th Digit do something
for (int i = 0; i < nCount; i = i + 3)
{
char c = ResultStr[i];
if (char.IsDigit(c))
{
int nChar = int.Parse(c.ToString());
ResultStr[i] = Char_CodeLib[nChar]; // 0..9
}
}
// Every N'th Digit do something
for (int i = 0; i < nCount; i = i + 4)
{
char c = ResultStr[i];
if (char.IsDigit(c))
{
int nChar = int.Parse(c.ToString());
ResultStr[i] = Char_CodeLib[nChar + 10]; // 10..19
}
}
// Add Randomness to the end of the string
Random random = new Random();
int nRand = random.Next(1, 9);
// Perform a Random Shift * So that the code ALWAYS looks different from use to use *
for (int i = 0; i < nCount; i = i + 2)
{
char c = ResultStr[i];
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()))
{
int nIndexShifted = Char_CodeLib.IndexOf(c) + nRand;
int nIndexShiftedAdj = nIndexShifted % 21;
ResultStr[i] = Char_CodeLib[nIndexShiftedAdj]; // 0..20
}
}
// Perform another Random Swap * So that the code ALWAYS looks different from use to use *
for (int i = 0; i < nCount; i = i + nRand)
{
char c = ResultStr[i];
int nOpposite = nCount - i - 1;
char o = ResultStr[nOpposite];
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()) &&
char.IsLetter(o) && !Char_CodeLibExcluded.Contains(o.ToString()))
{
// swap
ResultStr[i] = o;
ResultStr[nOpposite] = c;
}
}
// Perform a Reversal
for (int i = 0; i < (nCount / 2); ++i)
{
char N1 = ResultStr[i];
char N2 = ResultStr[nCount - 1 - i];
// swap
ResultStr[i] = N2;
ResultStr[nCount - 1 - i] = N1;
}
// Add the Randomness to the string for proper decoding to occur
ResultStr.Add(Char.Parse(nRand.ToString()));
// And Return
return new String(ResultStr.ToArray());
}
return String.Empty;
}
/// <summary>
/// * Simple Decoder *
/// </summary>
/// <param name="strAboutToBeDecodeShuffled"></param>
/// <returns></returns>
private string DecodeShuffle(string strAboutToBeDecodeShuffled)
{
const string Char_CodeLib = "ABCDEFGHIJKNOPQRSTUVW"; //20
const string Char_CodeLibExcluded = "LMXYZ"; //5
try
{
if (!String.IsNullOrEmpty(strAboutToBeDecodeShuffled))
{
List<char> ResultStr = new List<char>(strAboutToBeDecodeShuffled);
// retrieve Randomness Factor
char cLast = ResultStr[ResultStr.Count - 1];
ResultStr.RemoveAt(ResultStr.Count - 1);
int nCount = ResultStr.Count;
int nRand = int.Parse(cLast.ToString());
// Perform a Reversal
for (int i = 0; i < (nCount / 2); ++i)
{
char N1 = ResultStr[i];
char N2 = ResultStr[nCount - 1 - i];
// swap
ResultStr[i] = N2;
ResultStr[nCount - 1 - i] = N1;
}
// Perform another Random Swap * So that the code ALWAYS looks different from use to use *
for (int i = 0; i < nCount; i = i + nRand)
{
char c = ResultStr[i];
int nOpposite = nCount - i - 1;
char o = ResultStr[nOpposite];
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()) &&
char.IsLetter(o) && !Char_CodeLibExcluded.Contains(o.ToString()))
{
// swap
ResultStr[i] = o;
ResultStr[nOpposite] = c;
}
}
// Perform a Random Shift * So that the code ALWAYS looks different from use to use *
for (int i = 0; i < nCount; i = i + 2)
{
char c = ResultStr[i];
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()))
{
int nIndexShifted = Char_CodeLib.IndexOf(c) - nRand;
int nIndexShiftedAdj = (nIndexShifted < 0)? 21 + nIndexShifted : nIndexShifted;
ResultStr[i] = Char_CodeLib[nIndexShiftedAdj]; // 0..20
}
}
// Every N'th Digit do something
for (int i = 0; i < nCount; i = i + 4)
{
char c = ResultStr[i];
if (char.IsLetter(c) && !Char_CodeLibExcluded.Contains(c.ToString()))
{
int nIndex = Char_CodeLib.IndexOf(c);
if (nIndex >= 10)
{
nIndex = nIndex - 10;
if (nIndex >= 0 && nIndex <= 9)
ResultStr[i] = Char.Parse(nIndex.ToString()); // 11..19
}
}
}
// Every N'th Digit do something
for (int i = 0; i < nCount; i = i + 3)
{
char c = ResultStr[i];
if (char.IsLetter(c))
{
int nIndex = Char_CodeLib.IndexOf(c);
if (nIndex >= 0 && nIndex <= 9)
ResultStr[i] = Char.Parse(nIndex.ToString()); // 1..9
}
}
// And Return
return new String(ResultStr.ToArray());
}
}
catch (Exception) { /* ignore */ }
return String.Empty;
}
#endregion
}
}

View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Deployment.Application;
using Forms = System.Windows.Forms;
using System.Windows;
using System.Diagnostics;
using Watchdog.WatchdogLib.WinForms;
using System.IO;
namespace Watchdog
{
/// <summary>
/// Responsible for Dynamically Checking if there is an update available via ClickOnce
/// </summary>
public static class ClickOnceUpdater
{
/// <summary>
/// Construction
/// </summary>
static ClickOnceUpdater(){}
/// <summary>
/// Installs the Update and Restarts the Current Instance
/// </summary>
/// <returns>false if an error occured, if succesful * Will Restart the App *</returns>
internal static bool InstallUpdateAndRestartIfSuccessful()
{
try
{
UpdateCheckInfo info = null;
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
if (ad != null)
{
// Log this to make sure we are sane
App.log.Info("Success in retrieving Application Deployment Manifest. This is a ClickOnce App");
try
{
info = ad.CheckForDetailedUpdate();
}
catch (DeploymentDownloadException dde)
{
MsgBox.ShowInfo("The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later. Error: " + dde.Message, "Unable to Download", System.Windows.Forms.MessageBoxButtons.OK);
App.log.Info("The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later. Error: " + dde.Message);
return false;
}
catch (InvalidDeploymentException ide)
{
MsgBox.ShowError("Cannot check for a new version of the application. The ClickOnce deployment is corrupt. Please redeploy the application and try again. Error: " + ide.Message, "Invalid Deployment", System.Windows.Forms.MessageBoxButtons.OK);
App.log.Error("Cannot check for a new version of the application. The ClickOnce deployment is corrupt. Please redeploy the application and try again. Error: " + ide.Message);
return false;
}
catch (InvalidOperationException ioe)
{
MsgBox.ShowError("This application cannot be updated. It is likely not a ClickOnce application. Error: " + ioe.Message, "Invalid Operation", System.Windows.Forms.MessageBoxButtons.OK);
App.log.Error("This application cannot be updated. It is likely not a ClickOnce application. Error: " + ioe.Message);
return false;
}
if (info.UpdateAvailable)
{
Boolean doUpdate = true;
if (!info.IsUpdateRequired)
{
Forms.DialogResult dr = MsgBox.ShowInfo("An update is available. Would you like to update\nthe application now?", "Update Available", Forms.MessageBoxButtons.OKCancel);
if (!(Forms.DialogResult.OK == dr))
doUpdate = false;
}
else
{
// Display a message that the app MUST reboot. Display the minimum required version.
MsgBox.ShowInfo("This application has detected a mandatory update from your\ncurrent " +
"version to version " + info.MinimumRequiredVersion.ToString() +
".\nThe application will now install\nthe update and restart.",
"Update Available", System.Windows.Forms.MessageBoxButtons.OK);
App.log.Info("This application has detected a mandatory update from your current " +
"version to version " + info.MinimumRequiredVersion.ToString() +
". The application will now install the update and restart.");
}
if (doUpdate)
{
try
{
ad.Update();
App.log.Info("The application has been upgraded,and will now restart.");
// Restart the Application * Imp! Auto-Delay the Start of the new Watchdog Instance *
if(File.Exists(App.APPLICATION_CLICKONCE_STARTMENU_LINK))
Process.Start(App.APPLICATION_CLICKONCE_STARTMENU_LINK, "15");
// Auto-Update * No Need to Close Applications *
App.State_SpecialCircum_DontCloseApplicationsOnExit();
Application.Current.Shutdown();
return true;
}
catch (DeploymentDownloadException dde)
{
MsgBox.ShowError("Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later. Error: " + dde, "Update Error", System.Windows.Forms.MessageBoxButtons.OK);
App.log.Error("Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later. Error: " + dde);
return false;
}
}
}
else
{
App.log.Info("Newer Version not available at this time.");
MsgBox.ShowInfo("A newer version of the application\nis not available at this time. \n\nPlease try again later.", "Newer Version not available", System.Windows.Forms.MessageBoxButtons.OK);
}
}
}
catch (Exception) { /* ignore */ }
return false;
}
}
}

View File

@@ -0,0 +1,276 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BridgeConnector.Lib.Process;
using BridgeConnector.Lib.Tools;
using System.IO;
using BridgeConnector.Lib.File;
using BridgeConnector.Lib.XML;
using System.Reflection;
namespace Component.All
{
/// <summary>
/// Common Functions and Helpers Useful for all Installing activities.
/// </summary>
public static class Common
{
#region Public Definitions
public const string INSTALLED_COMPONENT_CONFIG_XML_FILENAME = "InstalledComponentConfig.xml";
public const string EMBEDDED_COMPONENT_CONFIG_XML_FILENAME = "EmbeddedComponentConfig.xml";
/// <summary>
/// Allow Setting of Log by external Assembly
/// </summary>
public static Logging Log
{
get
{
return s_Log;
}
set
{
if (value != null)
s_Log = value;
}
}
#endregion
#region Private Statics
private static ISReadWrite s_isrw = null;
private static XSerializer s_serializer = null;
private static ComponentConfig s_EmbeddedComponentConfig = null;
private static ComponentConfig s_InstalledComponentConfig = null;
private static Logging s_Log = null;
#endregion
#region Construction
/// <summary>
/// Responsible for reading in embedded and installed configuration
/// </summary>
static Common()
{
s_isrw = new ISReadWrite(INSTALLED_COMPONENT_CONFIG_XML_FILENAME);
s_serializer = new XSerializer();
//# Read in from Resource (Embedded Components)
s_EmbeddedComponentConfig = s_serializer.ReadFromResource<ComponentConfig>(Assembly.GetExecutingAssembly().GetManifestResourceStream("Component.All." + EMBEDDED_COMPONENT_CONFIG_XML_FILENAME));
if (s_EmbeddedComponentConfig == null)
throw new Exception("Could not read in EmbeddedComponentConfig"); // should never happen
//# Read in from IS (Currently Installed Components)
s_InstalledComponentConfig = s_isrw.ReadFromIS<ComponentConfig>();
if (s_InstalledComponentConfig == null)
s_InstalledComponentConfig = new ComponentConfig();
}
#endregion
#region Public Statics
/// <summary>
/// Retrieve the EmbeddedComponentConfig
/// </summary>
/// <returns>the EmbeddedComponentConfig</returns>
public static ComponentConfig EmbeddedConfig
{
get
{
return s_EmbeddedComponentConfig;
}
}
/// <summary>
/// Retrieve the InstalledComponentConfig
/// </summary>
/// <returns>the InstalledComponentConfig or null, if not existent</returns>
public static ComponentConfig InstalledConfig
{
get
{
return s_InstalledComponentConfig;
}
}
/// <summary>
/// Allows Caller to write out any changes to InstalledConfig back to the File
/// </summary>
public static void WriteOutChangesToInstalledConfig()
{
s_isrw.WriteToIS<ComponentConfig>(s_InstalledComponentConfig);
}
/// <summary>
/// Checks to see if any Components are installed. If this returns false, then this is a Fresh Install
/// </summary>
/// <returns>true, if any components are installed, false otherwise</returns>
public static bool AreAnyComponentsInstalled()
{
bool bIsInstalled = (InstalledConfig != null) && (InstalledConfig.BinaryComponents.Components.Length > 0 || InstalledConfig.SetupComponents.Components.Length > 0);
return bIsInstalled;
}
/// <summary>
/// Retrieves the Index for the Component that matches the specified Unique Label
/// </summary>
/// <param name="UniqueLabel">label to search components for</param>
/// <param name="components">a component array</param>
/// <returns>a value >=0 or -1, if not found</returns>
public static int GetIndexForComponentUniqueLabel(string UniqueLabel, ComponentConfig.Component[] components)
{
if (String.IsNullOrEmpty(UniqueLabel) || components == null || components.Length <= 0)
return -1;
for (int i = 0; i < components.Length; ++i)
{
if (String.Compare(components[i].UniqueLabel, UniqueLabel, true) == 0)
return i;
}
return -1;
}
/// <summary>
/// Spawn a Setup Process (Setup.exe for example)
/// </summary>
public static void PSetupSpwan(string SetupFileNameNPath, string param_s)
{
PStarter.StartProcess(PStartInfo.CreateProcess(SetupFileNameNPath, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, false), true, false);
}
/// <summary>
/// Spawn a MSI Setup Process (*.msi)
/// </summary>
public static void PSetupMSIEXEC(string param_s)
{
string msiexec = System.Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\msiexec.exe";
PStarter.StartProcess(PStartInfo.CreateProcess(msiexec, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, false), true, false);
}
/// <summary>
/// Run a command on the commandline * Hidden *
/// </summary>
/// <param name="cmdline">cmd to run</param>
public static string RunCmdLine(string cmdline)
{
string result = PStarter.RunDosCommand(cmdline);
return result;
}
/// <summary>
/// Use this to get the complete path to a .net framework utility like gacutil.exe or
/// installutil.exe.. any .net framework utility. Will fall back to look in the %temp% folder,
/// if not found, giving the opportunity to deploy the util directly with the components
/// </summary>
/// <param name="UtilFileName">the utility in .net you are looking for like gacutil.exe</param>
/// <returns>the full filenameNpath or "", if no existing file found</returns>
public static string GetNetFrameworkUtilFileNameNPathFile(string UtilFileName)
{
string windir = System.Environment.GetEnvironmentVariable("windir", EnvironmentVariableTarget.Machine);
string NetFramework1_0 = windir + "\\Microsoft.Net\\Framework\\v1.0.3705";
string NetFramework1_1 = windir + "\\Microsoft.Net\\Framework\\v1.1.4322";
string NetFramework2_0 = windir + "\\Microsoft.Net\\Framework\\v2.0.50727";
string NetFramework3_0 = windir + "\\Microsoft.Net\\Framework\\v3.0";
string NetFramework3_5 = windir + "\\Microsoft.Net\\Framework\\v3.5";
string NetFramework4_0 = windir + "\\Microsoft.Net\\Framework\\v4.0.30319";
string TempPath = PathNaming.PathEndsWithNoSlash(Path.GetTempPath()); // We use this as a Fallback, in case file doesn't exist in the framework
string[] Frameworks = new string[] { NetFramework2_0, NetFramework4_0, NetFramework1_0, NetFramework1_1, NetFramework3_0, NetFramework3_5, TempPath };
string NetUtilFileNameNPath = "";
foreach (string framework in Frameworks)
{
if (File.Exists(framework + "\\" + UtilFileName))
{
NetUtilFileNameNPath = framework + "\\" + UtilFileName;
return NetUtilFileNameNPath;
}
};
return NetUtilFileNameNPath;
}
/// <summary>
/// Quick Helper to get the Program Files Path for the specific system
/// </summary>
/// <returns>Program Files path with a '/' at the end</returns>
public static string GetProgramFilesPathOnSystemWithEndSlash()
{
string ProgramFiles = System.Environment.GetEnvironmentVariable("ProgramFiles(x86)");
if (String.IsNullOrEmpty(ProgramFiles))
ProgramFiles = System.Environment.GetEnvironmentVariable("ProgramFiles");
return PathNaming.PathEndsWithSlash(ProgramFiles);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string SetOwnership()
{
// in order to do any of this, sadly, we must first install the windows resource kit
//subinacl /subdirectories *.* /setowner=domainname\user
return String.Empty;
}
/// <summary>
/// To grant the specified User or group Full Control permissions to the folder and its contents
/// </summary>
/// <param name="FolderNPath">full path to folder/directory</param>
/// <param name="UserOrGroup">domainname\administrator, any windows user or group</param>
/// <returns></returns>
public static bool GrantFullPermissionToFolderForUserOrGroup(string FolderNPath, string UserOrGroup)
{
if (Directory.Exists(FolderNPath))
{
string command = String.Format("cacls \"{0}\" /t /e /g {1}:f", FolderNPath, UserOrGroup);
if (command.Contains("Invalid arguments."))
return false;
else
return true;
}
return false;
}
/// <summary>
/// Stop a service
/// </summary>
/// <param name="ServiceName">name of service to stop</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StopService(string ServiceName)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StopService(ServiceName, true, 120);
return bSuccess;
}
/// <summary>
/// start a service
/// </summary>
/// <param name="ServiceName">name of a service to start</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StartService(string ServiceName)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StartService(ServiceName, 120);
return bSuccess;
}
/// <summary>
/// Does Service Exist
/// </summary>
/// <param name="ServiceName">Name of service to check</param>
/// <returns>true if successful, false otherwise</returns>
public static bool ServiceExists(string ServiceName)
{
return ServiceW.DoesServiceExist(ServiceName);
}
#endregion
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace Component.All
{
/// <summary>
/// Install Configuration
/// </summary>
public enum InstallConfig
{
LytecMD,
MedisoftClinical,
}
/// <summary>
/// Common Functions and Helpers Useful for Lytec, Medisoft Installing activities
/// </summary>
public static class Common_MediLytec
{
/// <summary>
/// Common/Ofted used #Defs/Definitions associated with Lytec/Medisoft
/// </summary>
public static class MediLytecPoundDef
{
public const string BRIDGE_SERVICE_TITLE = "BridgeService";
public const string BRIDGE_SERVICE_ASSEMBLY = "BridgeService.exe";
public const string BRIDGE_SERVICE_NAME = "McKesson Bridge Service";
public const string MIRTH_SERVICE_NAME = "Mirth Connect Service";
public const string POSTGRE_SERVICE_NAME = "Mirth_Connect_PostgreSQL_Server";
public const string POSTGRE_SERVER_PORT = "5432";
}
/// <summary>
/// Retrieve the Configuration (Lytec/Medisoft) from the Registry
/// </summary>
/// <returns>Lytec/Medisoft</returns>
public static InstallConfig RetrieveInstallConfigFromRegistry()
{
bool bIsLytecInstalled = false;
try
{
RegistryKey reg = Registry.LocalMachine.OpenSubKey("Software\\Lytec", false);
bIsLytecInstalled = (reg != null);
if (!bIsLytecInstalled) // also check Wow64
{
reg = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Lytec", false);
bIsLytecInstalled = (reg != null);
}
}
catch (Exception) { /* ignore */ }
if (bIsLytecInstalled)
return InstallConfig.LytecMD;
else
return InstallConfig.MedisoftClinical;
}
}
}

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{94CB1BBA-5CF1-4155-827E-1527032D3921}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Component.All</RootNamespace>
<AssemblyName>Component.All</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Output\Debug\Components\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Output\Release\Components\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Common.cs" />
<Compile Include="Common_MediLytec.cs" />
<Compile Include="ComponentConfig.cs" />
<Compile Include="Component_Binary_Manager.cs" />
<Compile Include="Component_Setup_Manager.cs" />
<Compile Include="GenericInstaller.cs" />
<Compile Include="IInstallComponent.cs" />
<Compile Include="IManageComponents.cs" />
<Compile Include="ISetup.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\BridgeConnectorLib\BridgeConnectorLib.csproj">
<Project>{9F60FBD1-0DA0-4558-971F-5BA9EE44493A}</Project>
<Name>BridgeConnectorLib</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="EmbeddedComponentConfig.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,223 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Collections;
using BridgeConnector.Lib.Tools;
using System.IO;
namespace Component.All
{
/// <summary>
/// Serializable Xml Object used to store all Configuration data
/// </summary>
[XmlRoot("ComponentConfig", Namespace = "BridgeConnect", IsNullable = false)]
public class ComponentConfig
{
public ComponentW BinaryComponents = null;
public ComponentW SetupComponents = null;
/// <summary>
/// XML Embedded Component Configuration
/// </summary>
public ComponentConfig()
{
BinaryComponents = new ComponentW();
SetupComponents = new ComponentW();
}
/// <summary>
/// Wrapper class for multiple Components
/// </summary>
public class ComponentW
{
private ArrayList m_ArrayList;
public ComponentW()
{
m_ArrayList = new ArrayList();
}
[XmlElement("Component")]
public Component[] Components
{
get
{
Component[] components = new Component[m_ArrayList.Count];
m_ArrayList.CopyTo(components);
return components;
}
set
{
if (value == null) return;
Component[] components = (Component[])value;
m_ArrayList.Clear();
foreach (Component component in components)
AddUpdateComponent(component.UniqueLabel, component.Version, component.FileName);
}
}
#region Public Helpers
/// <summary>
/// Call this function to Add/Update a component
/// </summary>
/// <param name="UniqueLabel">unique label used to identify a component</param>
/// <param name="Version">Version of the component</param>
/// <param name="FileName">FileName of the component</param>
public void AddUpdateComponent(string UniqueLabel, string Version, string FileName)
{
int nIndex = GetIndexForComponent(UniqueLabel);
if (nIndex != -1)
{
Component component = ((Component)m_ArrayList[nIndex]);
component.UniqueLabel = UniqueLabel;
component.Version = Version;
component.FileName = FileName;
}
else
{
m_ArrayList.Add(new Component(UniqueLabel, Version, FileName));
}
}
/// <summary>
/// Call this function to remove a component from the list
/// </summary>
/// <param name="UniqueLabel">unique label used to identify a component</param>
public void RemoveComponent(string UniqueLabel)
{
int nIndex = GetIndexForComponent(UniqueLabel);
if (nIndex != -1)
m_ArrayList.RemoveAt(nIndex);
}
/// <summary>
/// Checks to see if a component already exists
/// </summary>
/// <param name="UniqueLabel">unique name identifying the component</param>
/// <returns>true for yes, no otherwise</returns>
public bool ComponentExists(string UniqueLabel)
{
return (GetIndexForComponent(UniqueLabel) != -1);
}
/// <summary>
/// Retrieves the component for the specified UniqueLabel
/// </summary>
/// <param name="UniqueLabel">unique name identifying the component</param>
/// <returns>the Component for the Label, or null if not found</returns>
public Component GetComponent(string UniqueLabel)
{
int nIndex = GetIndexForComponent(UniqueLabel);
if (nIndex != -1)
return (Component) m_ArrayList[nIndex];
else
return null;
}
#endregion
#region Internal & Private Helpers
/// <summary>
/// gets the index in the array list for the specified component
/// </summary>
/// <param name="UniqueLabel">unique name identifying the component</param>
/// <returns>index >= 0 or -1 if not found</returns>
private int GetIndexForComponent(string UniqueLabel)
{
for (int i = 0; i < m_ArrayList.Count; ++i)
{
Component component = (Component)m_ArrayList[i];
if (String.Compare(component.UniqueLabel, UniqueLabel, true) == 0)
return i;
}
return -1;
}
#endregion
}
/// <summary>
/// specify the Component
/// </summary>
public class Component : IComparable
{
public Component() { }
public Component(string UniqueLabel, string Version, string FileName) { this.UniqueLabel = UniqueLabel; this.Version = Version; this.FileName = FileName; }
[XmlText]
public string FileName = "";
/// <summary>
/// In case a component has multiple files, seperated by a ';', internally we should always call this
/// </summary>
public string[] FileNames
{
get
{
if (!String.IsNullOrEmpty(FileName))
{
if (FileName.Contains(';'))
return FileName.Split(';');
else
return new string[] { FileName };
}
return new string[] { };
}
}
[XmlAttribute("UniqueLabel")]
public string UniqueLabel = "";
[XmlAttribute("Version")]
public string Version = "";
/// <summary>
/// In case a component has multiple files, seperated by a ';', internally we should always call this
/// </summary>
public string[] TempFileNamesNPath
{
get
{
string[] files = FileNames;
List<string> tFiles = new List<string>();
if (files != null)
{
string strPath = PathNaming.PathEndsWithSlash(Path.GetTempPath());
foreach (string file in files)
tFiles.Add(strPath + file);
return tFiles.ToArray();
}
return new string[] { };
}
}
#region IComparable Members
/// <summary>
/// Compares the Components Unique Label and Version
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int CompareTo(object obj)
{
if (obj is Component)
{
Component c = (Component)obj;
int nCompare = String.Compare(this.UniqueLabel, c.UniqueLabel, true);
if (nCompare == 0)
nCompare = String.Compare(this.Version, c.Version, true);
return nCompare;
}
else
{
throw new ArgumentException("object is not a Component");
}
}
#endregion
}
}
}

View File

@@ -0,0 +1,277 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BridgeConnector.Lib.File;
using System.Xml.Serialization;
using System.Collections;
using BridgeConnector.Lib.XML;
using System.Resources;
using System.Reflection;
using System.IO;
using BridgeConnector.Lib.Tools;
using BridgeConnector.Lib.Assembly;
namespace Component.All
{
/// <summary>
/// Responsible for extracting the Components that are embedded in this dll
/// into the temporary directory for the installer to consume
/// </summary>
public class Component_Binary_Manager : IDisposable, IManageComponents
{
#region Private Members
private bool _disposed = false;
private Dictionary<string, Assembly> _componentsLoaded = new Dictionary<string, Assembly>();
#endregion
#region Construction
/// <summary>
/// Constructor
/// </summary>
public Component_Binary_Manager()
{
}
/// <summary>
/// Finalizer
/// </summary>
~Component_Binary_Manager()
{
Dispose(true);
}
#endregion
#region IManageComponents Members
/// <summary>
/// Checks if there are Newer Components embedded then that were installed on the system
/// </summary>
/// <returns>true, if newer components were found, false otherwise</returns>
public bool AreNewerComponentsAvailable()
{
//# If nothing is installed, no need to continue
if (GetAllInstalledComponents() == null)
return true;
// if the lengths don't match, something must get installed
if (GetAllInstalledComponents().Length != GetAllEmbeddedComponents().Length)
return true;
// # Otherwise, let's determine 1 by 1
foreach (ComponentConfig.Component component in GetAllEmbeddedComponents())
{
int nIndex = Common.GetIndexForComponentUniqueLabel(component.UniqueLabel, GetAllInstalledComponents());
if (nIndex == -1)
return true;
else if(GetAllInstalledComponents()[nIndex].CompareTo(component) != 0)
return true;
}
return false;
}
/// <summary>
/// Returns the Component Definition containing the temporary file (extracted component)
/// for all Newer components found on the system
/// </summary>
/// <param name="setupEventObj">Setup Event Object is passed, for component manager to pass down to it's components</param>
/// <returns>a list of newer binary components, or empty list for none</returns>
public IInstallComponent[] GetNewerComponents(ref SetupEvents setupEventObj)
{
// # Extract all, or let's determine 1 by 1 and extract
bool bInstalledCompsFound = (GetAllInstalledComponents() != null);
foreach (ComponentConfig.Component component in GetAllEmbeddedComponents())
{
bool bExtract = true;
if (bInstalledCompsFound)
{
int nIndex = Common.GetIndexForComponentUniqueLabel(component.UniqueLabel, GetAllInstalledComponents());
if (nIndex != -1)
bExtract = (GetAllInstalledComponents()[nIndex].CompareTo(component) != 0);
}
// mark component for Installation * Extract to File System *
if (bExtract)
{
if (!ExtractComponentFromResourceToTempFileLocation(component))
Common.Log.Error(String.Format("Failed to Extract Component {0}", component.UniqueLabel));
}
}
List<IInstallComponent> ComponentsToInstall = new List<IInstallComponent>();
if (_componentsLoaded.Count > 0)
{
foreach(Assembly asm in _componentsLoaded.Values)
{
IInstallComponent installComp = null;
Type[] types = asm.GetTypes();
foreach (Type t in types)
{
if (t.GetInterface(typeof(IInstallComponent).Name) != null)
{
installComp = (IInstallComponent) asm.CreateInstance(t.FullName);
break;
}
}
// Check IInstallComponent was found
if (installComp == null)
{
Common.Log.Error(String.Format("Component {0} contains no IInstallComponent Definition.", AssemblyW.GetAssemblyName(asm)));
continue;
}
// Check if class also implements ISetup
if(installComp is ISetup)
((ISetup) installComp).ComponentLoaded(ref setupEventObj);
// Add to Install Components
ComponentsToInstall.Add(installComp);
}
}
return ComponentsToInstall.ToArray();
}
/// <summary>
/// Retrieves the list of all installed components, in order to uninstall
/// </summary>
/// <returns>a list of all installed components, null otherwise</returns>
public IInstallComponent[] GetAllInstalledComponents(string ComponentsSeperatedbySemiColonOrBlankForAll, ref SetupEvents setupEventObj)
{
// TO DO:
return null;
}
/// <summary>
/// Retrieves the list of all installed components
/// </summary>
/// <returns>a list of all installed components, null otherwise</returns>
public ComponentConfig.Component[] GetAllInstalledComponents()
{
if (Common.InstalledConfig != null && Common.InstalledConfig.BinaryComponents.Components.Length > 0)
return Common.InstalledConfig.BinaryComponents.Components;
return null;
}
/// <summary>
/// Retrieves the list of all installed componentsW
/// </summary>
/// <returns>a list of all installed componentsW, null otherwise</returns>
public ComponentConfig.ComponentW GetAllInstalledComponentsW()
{
return Common.InstalledConfig.BinaryComponents;
}
/// <summary>
/// Retrieves the list of all Embedded components
/// </summary>
/// <returns>a list of all embedded components, null otherwise</returns>
public ComponentConfig.Component[] GetAllEmbeddedComponents()
{
if (Common.EmbeddedConfig != null && Common.EmbeddedConfig.BinaryComponents.Components.Length > 0)
return Common.EmbeddedConfig.BinaryComponents.Components;
return null;
}
#endregion
#region Private Helpers
/// <summary>
/// Private Helper to physically extract the bits from the resource and write them to a temporary
/// file location
/// </summary>
/// <param name="component">Component, whose files are to be extracted</param>
/// <returns>true, if successful, false otherwise</returns>
private bool ExtractComponentFromResourceToTempFileLocation(ComponentConfig.Component component)
{
if (component != null)
{
// Extract the component to the Temp Directory,
// if it is not already there...
for (int i = 0; i < component.FileNames.Length; ++i)
{
// First try loading the assembly
string asmName = "Component.Binary." + component.UniqueLabel;
Assembly asm = Assembly.Load(asmName);
if (asm == null)
return false;
else
_componentsLoaded[component.UniqueLabel] = asm; // <- imp
string FileName = component.FileNames[i];
string TempFileNameNPath = component.TempFileNamesNPath[i];
if (!File.Exists(TempFileNameNPath))
{
using (BinaryReader br = new BinaryReader(asm.GetManifestResourceStream(asmName + "." + FileName)))
using (BinaryWriter bw = new BinaryWriter(new FileStream(TempFileNameNPath, FileMode.Create)))
{
byte[] buffer = new byte[64 * 1024];
int numread = br.Read(buffer, 0, buffer.Length);
while (numread > 0)
{
bw.Write(buffer, 0, numread);
numread = br.Read(buffer, 0, buffer.Length);
}
bw.Flush();
}
}
}
return true;
}
return false;
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose of all extracted files
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Make sure to conserve disk space, to delete all files that were extracted
/// by this program
/// </summary>
/// <param name="disposing">if true, delete all files extracted by this dll</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// When Disposing, Delete all Temporary Files on the System that may exist
foreach (ComponentConfig.Component component in GetAllEmbeddedComponents())
{
foreach (string tFileNameNPath in component.TempFileNamesNPath)
{
if (File.Exists(tFileNameNPath))
File.Delete(tFileNameNPath);
}
}
_componentsLoaded.Clear();
_componentsLoaded = null;
}
// Indicate that the instance has been disposed.
_disposed = true;
}
}
#endregion
}
}

View File

@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using BridgeConnector.Lib.Assembly;
namespace Component.All
{
/// <summary>
/// Responsible for working with setup components which don't require any special treatment
/// </summary>
public class Component_Setup_Manager : IDisposable, IManageComponents
{
#region Private Members
private bool _disposed = false;
private Dictionary<string, Assembly> _componentsLoaded = new Dictionary<string, Assembly>();
#endregion
#region Construction
/// <summary>
/// Constructor
/// </summary>
public Component_Setup_Manager()
{
}
/// <summary>
/// Finalizer
/// </summary>
~Component_Setup_Manager()
{
Dispose(true);
}
#endregion
#region IManageComponents Members
/// <summary>
/// Checks if there are Newer Components embedded then that were installed on the system
/// </summary>
/// <returns>true, if newer components were found, false otherwise</returns>
public bool AreNewerComponentsAvailable()
{
//# If nothing is installed, no need to continue
if (GetAllInstalledComponents() == null)
return true;
// if the lengths don't match, something must get installed
if (GetAllInstalledComponents().Length != GetAllEmbeddedComponents().Length)
return true;
// # Otherwise, let's determine 1 by 1
foreach (ComponentConfig.Component component in GetAllEmbeddedComponents())
{
int nIndex = Common.GetIndexForComponentUniqueLabel(component.UniqueLabel, GetAllInstalledComponents());
if (nIndex == -1)
return true;
else if (GetAllInstalledComponents()[nIndex].CompareTo(component) != 0)
return true;
}
return false;
}
/// <summary>
/// Returns the Component Definitions for all Newer components found on the system
/// </summary>
/// <returns>a list of newer setup components, or empty list for none</returns>
public IInstallComponent[] GetNewerComponents(ref SetupEvents setupEventObj)
{
// # Extract all, or let's determine 1 by 1 and extract
bool bInstalledCompsFound = (GetAllInstalledComponents() != null);
foreach (ComponentConfig.Component component in GetAllEmbeddedComponents())
{
bool bInstall = true;
if (bInstalledCompsFound)
{
int nIndex = Common.GetIndexForComponentUniqueLabel(component.UniqueLabel, GetAllInstalledComponents());
if (nIndex != -1)
bInstall = (GetAllInstalledComponents()[nIndex].CompareTo(component) != 0);
}
// mark component for Installation
if (bInstall)
{
string asmName = "Component.Setup." + component.UniqueLabel;
_componentsLoaded[component.UniqueLabel] = Assembly.Load(asmName);
}
}
List<IInstallComponent> ComponentsToInstall = new List<IInstallComponent>();
if (_componentsLoaded.Count > 0)
{
foreach (Assembly asm in _componentsLoaded.Values)
{
IInstallComponent installComp = null;
Type[] types = asm.GetTypes();
foreach (Type t in types)
{
if (t.GetInterface(typeof(IInstallComponent).Name) != null)
{
installComp = (IInstallComponent)asm.CreateInstance(t.FullName);
break;
}
}
// Check IInstallComponent was found
if (installComp == null)
{
Common.Log.Error(String.Format("Component {0} contains no IInstallComponent Definition.", AssemblyW.GetAssemblyName(asm)));
continue;
}
// Check if class also implements ISetup
if (installComp is ISetup)
((ISetup)installComp).ComponentLoaded(ref setupEventObj);
// Add to Install Components
ComponentsToInstall.Add(installComp);
}
}
return ComponentsToInstall.ToArray();
}
/// <summary>
/// Retrieves the list of all installed components, in order to uninstall
/// </summary>
/// <returns>a list of all installed components, null otherwise</returns>
public IInstallComponent[] GetAllInstalledComponents(string ComponentsSeperatedbySemiColonOrBlankForAll, ref SetupEvents setupEventObj)
{
// TO DO:
//string[] ComponentsUniqueLabels = null;
//if (!String.IsNullOrEmpty(ComponentsSeperatedbySemiColonOrBlankForAll))
// ComponentsUniqueLabels = ComponentsSeperatedbySemiColonOrBlankForAll.Split(';');
return null;
}
/// <summary>
/// Retrieves the list of all installed components
/// </summary>
/// <returns>a list of all installed components, null otherwise</returns>
public ComponentConfig.Component[] GetAllInstalledComponents()
{
if (Common.InstalledConfig != null && Common.InstalledConfig.SetupComponents.Components.Length > 0)
return Common.InstalledConfig.SetupComponents.Components;
return null;
}
/// <summary>
/// Retrieves the list of all installed componentsW
/// </summary>
/// <returns>a list of all installed componentsW, null otherwise</returns>
public ComponentConfig.ComponentW GetAllInstalledComponentsW()
{
return Common.InstalledConfig.SetupComponents;
}
/// <summary>
/// Retrieves the list of all Embedded components
/// </summary>
/// <returns>a list of all embedded components, null otherwise</returns>
public ComponentConfig.Component[] GetAllEmbeddedComponents()
{
if (Common.EmbeddedConfig != null && Common.EmbeddedConfig.SetupComponents.Components.Length > 0)
return Common.EmbeddedConfig.SetupComponents.Components;
return null;
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose of all extracted files
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Make sure to conserve disk space, to delete all files that were extracted
/// by this program
/// </summary>
/// <param name="disposing">if true, delete all files extracted by this dll</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_componentsLoaded.Clear();
_componentsLoaded = null;
}
// Indicate that the instance has been disposed.
_disposed = true;
}
}
#endregion
}
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<ComponentConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="BridgeConnect">
<BinaryComponents>
<Component UniqueLabel="Java" Version="1.6.0_27">jre-6u27-windows-i586-s.exe</Component>
<Component UniqueLabel="PostgreSql" Version="9.1.1-1">postgresql-9.1.1-1-windows.exe</Component>
<Component UniqueLabel="PostgreSql_Admin" Version="1.14.0">pgadmin3-1.14.0.msi</Component>
<Component UniqueLabel="PostgreSql_Devart" Version="5.50.228.0">Devart.Data.dll;Devart.Data.PostgreSql.dll;Devart.Data.PostgreSql.xml;gacutil.exe;gacutil.exe.config</Component>
<Component UniqueLabel="Mirth" Version="2.1.1.5490.b781">mirthconnect-2.1.1.5490.b781-windows.exe</Component>
</BinaryComponents>
<SetupComponents>
<Component UniqueLabel="BridgeService" Version="1.0.0.0">BridgeService.exe</Component>
</SetupComponents>
</ComponentConfig>

View File

@@ -0,0 +1,328 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BridgeConnector.Lib.Thread;
namespace Component.All
{
/// <summary>
/// Calls GenericInstaller in order to perform an install/uninstall
/// * Does so in a threaded fashion *
/// </summary>
public class GenericInstall
{
// Let the Caller know that a) the thread Completed b) it did so successfully
public static bool s_PerformInstallCompleted = false;
public static bool s_PerformInstallCompletedSuccessfully = false;
// Let the Caller know that a) the thread Completed b) it did so successfully
public static bool s_PerformUninstallCompleted = false;
public static bool s_PerformUninstallCompletedSuccessfully = false;
// Private ComponentMgmtObjects
private static GenericInstaller<Component_Binary_Manager> s_binaryInstaller = null;
private static GenericInstaller<Component_Setup_Manager> s_setupInstaller = null;
private static SetupEvents s_SetupEvents = new SetupEvents();
/// <summary>
/// Perform a Threaded Install
/// </summary>
public static void PerformInstall()
{
TStarter.ThreadMethod tMethod = delegate()
{
s_PerformInstallCompleted = false;
s_PerformInstallCompletedSuccessfully = false;
bool bBinaryInstallNeeded = false;
bool bSetupInstallNeeded = false;
// # Let's see if we need to update/install Binary Components
if(s_binaryInstaller == null)
s_binaryInstaller = new GenericInstaller<Component_Binary_Manager>();
bBinaryInstallNeeded = s_binaryInstaller.IsInstallNeeded(ref s_SetupEvents);
// # Let's see if we need to update/install Setup Components
if(s_setupInstaller == null)
s_setupInstaller = new GenericInstaller<Component_Setup_Manager>();
bSetupInstallNeeded = s_setupInstaller.IsInstallNeeded(ref s_SetupEvents);
// # Let's Install, Baby...
if (bBinaryInstallNeeded || bSetupInstallNeeded)
{
// # Trigger Start Install Event
s_SetupEvents.Raise_Before_Install_Event();
bool bBinarySuccess = true;
bool bSetupbSuccess = true;
// update/install Binary Components
if (bBinaryInstallNeeded)
bBinarySuccess = s_binaryInstaller.Install();
// update/install Setup Components
if (bSetupInstallNeeded)
bSetupbSuccess = s_setupInstaller.Install();
// # Trigger End Install Event
if (bBinaryInstallNeeded || bSetupInstallNeeded)
s_SetupEvents.Raise_After_Install_Event();
// # We fail if one of them fails
s_PerformInstallCompletedSuccessfully = bBinarySuccess && bSetupbSuccess;
}
// # Let External Callers know that this Thread Completed
s_PerformInstallCompleted = true;
};
TStarter.StartThread(tMethod, "PerformInstall", System.Threading.ApartmentState.MTA, false, System.Threading.ThreadPriority.Normal);
}
/// <summary>
/// Perform a Threaded Uninstall
/// </summary>
public static void PerformUninstall(string ComponentsSeperatedbySemiColonOrBlankForAll)
{
s_PerformUninstallCompleted = false;
s_PerformUninstallCompletedSuccessfully = false;
}
/// <summary>
/// Call this function to let every object know that either PerformInstall or PerformUninstall was called,
/// the Gui then may have made some other modifications, and we are now completed
/// </summary>
public static void SetupMainCompleted()
{
// Notify all components that Setup is now complete
s_SetupEvents.Raise_Ending_Setup_Event();
// # Imp! - We must call dispose on our Setup Objects
if (s_binaryInstaller != null)
{
s_binaryInstaller.Dispose();
s_binaryInstaller = null;
}
if (s_setupInstaller != null)
{
s_setupInstaller.Dispose();
s_setupInstaller = null;
}
}
}
/// <summary>
/// Generic Install Class used for IManageComponents
/// </summary>
/// <typeparam name="T">IManageComponents responsible for Installing</typeparam>
public class GenericInstaller<T> : IDisposable where T : IManageComponents, IDisposable, new()
{
#region Private Members
private T _ComponentMGR = default(T);
private IInstallComponent[] _ComponentsToPerformWorkOn = null;
private bool _disposed = false;
#endregion
#region Construction
/// <summary>
/// Construct the T Object
/// </summary>
public GenericInstaller()
{
_ComponentMGR = new T();
}
/// <summary>
/// Finalizer
/// </summary>
~GenericInstaller()
{
Dispose(true);
}
#endregion
#region Public Methods
/// <summary>
///
/// </summary>
/// <param name="setupEventObj"></param>
/// <returns></returns>
public bool IsInstallNeeded(ref SetupEvents setupEventObj)
{
if (_ComponentMGR.AreNewerComponentsAvailable())
{
Common.Log.Info(String.Format("Newer Components available for Type {0}.", _ComponentMGR.GetType().Name));
_ComponentsToPerformWorkOn = _ComponentMGR.GetNewerComponents(ref setupEventObj);
if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0)
{
Common.Log.Info(String.Format("Found {0} Newer Components.", _ComponentsToPerformWorkOn.Length));
return true;
}
}
Common.Log.Info(String.Format("No Newer Components available for Type {0}.", _ComponentMGR.GetType().Name));
return false;
}
/// <summary>
/// Perform Install on the IManageComponents specified when Constructing the GenericInstaller Object
/// </summary>
/// <returns>true if no error occurs, false otherwise</returns>
public bool Install()
{
bool bErrorsOccured = false;
List<ComponentConfig.Component> successfullyInstalledComponents = new List<ComponentConfig.Component>();
if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0)
{
// # Start Install
foreach (IInstallComponent installComp in _ComponentsToPerformWorkOn)
{
ComponentConfig.Component component = installComp.GetComponent();
if (installComp.BEFORE_INSTALLING_COMPONENT())
{
Common.Log.Info(String.Format("Installing Component {0} with Version {1}.", component.UniqueLabel, component.Version));
bool bInstallSuccess = installComp.INSTALL_COMPONENT();
bInstallSuccess = bInstallSuccess && installComp.AFTER_INSTALLING_COMPONENT();
if (bInstallSuccess)
{
Common.Log.Info(String.Format("Component {0} with version {1} was correctly installed.", component.UniqueLabel, component.Version));
successfullyInstalledComponents.Add(component);
}
else
{
bErrorsOccured = true;
string msg = String.Format("Component {0} with version {1} was not correctly installed.", component.UniqueLabel, component.Version);
Common.Log.Error(msg);
}
}
}
// # End Install
// Add any installed components to the Installed Configuration
foreach (ComponentConfig.Component component in successfullyInstalledComponents)
_ComponentMGR.GetAllInstalledComponentsW().AddUpdateComponent(component.UniqueLabel, component.Version, component.FileName);
// Write out the installed Configuration
Common.WriteOutChangesToInstalledConfig();
}
Common.Log.Info(String.Format("Exiting Install() for Type {0} with bErrorsOccured set to = {1}", _ComponentMGR.GetType().Name, bErrorsOccured));
return !bErrorsOccured;
}
/// <summary>
///
/// </summary>
/// <param name="setupEventObj"></param>
/// <returns></returns>
public bool IsUninstallNeeded(ref SetupEvents setupEventObj, string ComponentsSeperatedbySemiColonOrBlankForAll)
{
if(_ComponentMGR.GetAllInstalledComponents() != null)
{
Common.Log.Info(String.Format("Installed Components available for Type {0}.", _ComponentMGR.GetType().Name));
_ComponentsToPerformWorkOn = _ComponentMGR.GetAllInstalledComponents(ComponentsSeperatedbySemiColonOrBlankForAll, ref setupEventObj);
if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0)
{
Common.Log.Info(String.Format("Found {0} Components to Uninstall.", _ComponentsToPerformWorkOn.Length));
return true;
}
}
Common.Log.Info(String.Format("No Installed Components to Uninstall for Type {0}.", _ComponentMGR.GetType().Name));
return false;
}
/// <summary>
/// Perform Uninstall on the IManageComponents specified when Constructing the GenericInstaller Object
/// </summary>
/// <param name="ComponentsSeperatedbySemiColonOrBlankForAll">coma-seperated Unique Labels of components to uninstall, blank for all</param>
/// <returns>true if no error occurs, false otherwise</returns>
public bool Uninstall(ref SetupEvents setupEventObj, string ComponentsSeperatedbySemiColonOrBlankForAll)
{
bool bErrorsOccured = false;
List<ComponentConfig.Component> successfullyUninstalledComponents = new List<ComponentConfig.Component>();
if (_ComponentsToPerformWorkOn != null && _ComponentsToPerformWorkOn.Length > 0)
{
// # Start Uninstall
foreach (IInstallComponent uninstallComp in _ComponentsToPerformWorkOn)
{
if (!uninstallComp.SUPPORTS_UNINSTALL()) // Not all components support uninstall * although they should, we should allow for this contigency
continue;
ComponentConfig.Component component = uninstallComp.GetComponent();
if (uninstallComp.BEFORE_UNINSTALLING_COMPONENT())
{
Common.Log.Info(String.Format("About to Uninstall Component {0} with Version {1}.", component.UniqueLabel, component.Version));
bool bUninstallSuccess = uninstallComp.UNINSTALL_COMPONENT();
if (!bUninstallSuccess)
bErrorsOccured = true;
bUninstallSuccess = bUninstallSuccess && uninstallComp.AFTER_UNINSTALLING_COMPONENT();
if (bUninstallSuccess)
{
Common.Log.Info(String.Format("Component {0} with version {1} was uninstalled.", component.UniqueLabel, component.Version));
successfullyUninstalledComponents.Add(component);
}
else
{
string msg = String.Format("Component {0} with version {1} was not uninstalled.", component.UniqueLabel, component.Version);
Common.Log.Error(msg);
}
}
}
// # End Uninstall
// Remove any uninstalled components from the Installed Configuration
foreach (ComponentConfig.Component component in successfullyUninstalledComponents)
_ComponentMGR.GetAllInstalledComponentsW().RemoveComponent(component.UniqueLabel);
// Write out the installed Configuration
Common.WriteOutChangesToInstalledConfig();
}
Common.Log.Info(String.Format("Exiting Uninstall() for Type {0} with bErrorsOccured set to = {1}", _ComponentMGR.GetType().Name, bErrorsOccured));
return !bErrorsOccured;
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose of all extracted files
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Make sure to call Dispose on the ComponentMGR for it to perform any cleanup
/// </summary>
/// <param name="disposing">if true, dispose ComponentMGR</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_ComponentMGR.Dispose();
_ComponentMGR = default(T);
}
// Indicate that the instance has been disposed.
_disposed = true;
}
}
#endregion
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Component.All
{
/// <summary>
/// All Components that install themselves must support this interface
/// </summary>
public interface IInstallComponent
{
/// <summary>
/// Get the Corresponding Component for this IInstallComponent
/// </summary>
/// <returns>the component for this IInstallCompoent</returns>
ComponentConfig.Component GetComponent();
/// <summary>
/// Used to determine if the component is needed to install
/// </summary>
/// <returns>true to continue to Install, false otherwise</returns>
bool BEFORE_INSTALLING_COMPONENT();
/// <summary>
/// Used to install a component
/// </summary>
/// <returns>true, if install was successful, false otherwise</returns>
bool INSTALL_COMPONENT();
/// <summary>
/// Used to do any validation after install occured
/// </summary>
/// <returns>true, if validation was successful, false otherwise</returns>
bool AFTER_INSTALLING_COMPONENT();
/// <summary>
/// Used to determine if the component supports uninstalling
/// </summary>
/// <returns>true, if component supports uninstalling, false otherwise</returns>
bool SUPPORTS_UNINSTALL();
/// <summary>
/// Used to determine if the component is needed to uninstall
/// </summary>
/// <returns>true to continue to uninstall, false otherwise</returns>
bool BEFORE_UNINSTALLING_COMPONENT();
/// <summary>
/// Used to uninstall a component
/// </summary>
/// <returns>true, if uninstall was successful, false otherwise</returns>
bool UNINSTALL_COMPONENT();
/// <summary>
/// Used to do any validation after uninstall occured
/// </summary>
/// <returns>true, if validation was successful, false otherwise</returns>
bool AFTER_UNINSTALLING_COMPONENT();
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Component.All
{
/// <summary>
/// Used by the Binary and Setup Component Manager,
/// could possible be reused later for a new Component Manager
/// </summary>
public interface IManageComponents
{
/// <summary>
/// Quick Check to see if newer Components are available
/// </summary>
/// <returns>true, if newer components are available, false otherwise</returns>
bool AreNewerComponentsAvailable();
/// <summary>
/// Retrieves the list of newer components that need to be installed
/// </summary>
/// <param name="setupEventObj">Setup Event Object is passed, for component manager to pass down to it's components</param>
/// <returns>a list of newer components to install, null otherwise</returns>
IInstallComponent[] GetNewerComponents(ref SetupEvents setupEventObj);
/// <summary>
/// Retrieves the list of all installed components, in order to uninstall
/// </summary>
/// <param name="ComponentsSeperatedbySemiColonOrBlankForAll">Specify Component Filter</param>
/// <param name="setupEventObj">Setup Event Object is passed, for component manager to pass down to it's components</param>
/// <returns>a list of all installed components, null otherwise</returns>
IInstallComponent[] GetAllInstalledComponents(string ComponentsSeperatedbySemiColonOrBlankForAll, ref SetupEvents setupEventObj);
/// <summary>
/// Retrieves the list of all installed components
/// </summary>
/// <returns>a list of all installed components, null otherwise</returns>
ComponentConfig.Component[] GetAllInstalledComponents();
/// <summary>
/// Retrieves the list of all installed componentsW
/// </summary>
/// <returns>a list of all installed componentsW, null otherwise</returns>
ComponentConfig.ComponentW GetAllInstalledComponentsW();
/// <summary>
/// Retrieves the list of all Embedded components
/// </summary>
/// <returns>a list of all embedded components, null otherwise</returns>
ComponentConfig.Component[] GetAllEmbeddedComponents();
}
}

View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Component.All
{
/// <summary>
/// Class is passed into ISetup ComponentLoaded() giving each component
/// a chance to subscribe to it
/// </summary>
public class SetupEvents
{
#region Events
/// <summary>
/// Delegate used to handle Setup Events
/// </summary>
public delegate void SetupEvent();
/// <summary>
/// Called after the entire Setup Application ends
/// </summary>
public event SetupEvent Ending_Setup;
/// <summary>
/// Called before the entire Install Process Begins
/// </summary>
public event SetupEvent Before_Install;
/// <summary>
/// Called after the entire Install Process ends
/// </summary>
public event SetupEvent After_Install;
/// <summary>
/// Called before the entire Uninstall Process Begins
/// </summary>
public event SetupEvent Before_Uninstall;
/// <summary>
/// Called after the entire Uninstall Process ends
/// </summary>
public event SetupEvent After_Uninstall;
#endregion
# region Event Raisers
/// <summary>
/// Raise the Ending Setup Event
/// </summary>
public void Raise_Ending_Setup_Event()
{
if (Ending_Setup != null)
Ending_Setup();
}
/// <summary>
/// Raise the Before Install Event
/// </summary>
public void Raise_Before_Install_Event()
{
if (Before_Install != null)
Before_Install();
}
/// <summary>
/// Raise the After Install Event
/// </summary>
public void Raise_After_Install_Event()
{
if (After_Install != null)
After_Install();
}
/// <summary>
/// Raise the Before Uninstall Event
/// </summary>
public void Raise_Before_Uninstall_Event()
{
if (Before_Uninstall != null)
Before_Uninstall();
}
/// <summary>
/// Raise the After Uninstall Event
/// </summary>
public void Raise_After_Uninstall_Event()
{
if (After_Uninstall != null)
After_Uninstall();
}
#endregion
}
/// <summary>
/// All Components that install themselves will implement this interface, if they are interested to
/// listen to / Handle Setup Events
/// </summary>
public interface ISetup
{
/// <summary>
/// Called when the Component is loaded. Components are only loaded
/// when an Install on them is iminent. The component has a chance to
/// listen to/handle events in the setup process.
/// </summary>
void ComponentLoaded(ref SetupEvents subscribeToDesiredEvents);
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Components")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Components")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ae8a648a-90cf-48ce-9b71-6e6b4cc417aa")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,7 @@
<Window x:Class="Watchdog.HiddenMainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="Window_Loaded" Closed="Window_Closed">
<Grid>
</Grid>
</Window>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Component.All;
using BridgeConnector.Lib.File;
namespace Component.Binary.Mirth
{
public class InstallComponent : IInstallComponent , ISetup
{
public const string MIRTH_SERVICE_NAME = Common_MediLytec.MediLytecPoundDef.MIRTH_SERVICE_NAME;
private const string POSTGRE_SERVICE_NAME = Common_MediLytec.MediLytecPoundDef.POSTGRE_SERVICE_NAME;
#region IInstallComponent Members
public ComponentConfig.Component GetComponent()
{
return Common.EmbeddedConfig.BinaryComponents.GetComponent("Mirth");
}
public bool BEFORE_INSTALLING_COMPONENT()
{
bool bSuccess = Common.StopService(MIRTH_SERVICE_NAME);
if (!bSuccess)
{
Common.Log.Error(String.Format("Failed to stop {0}", MIRTH_SERVICE_NAME));
return false;
}
string result = Common.RunCmdLine("netsh firewall set portopening tcp 8080 MirthConnectAdministrator ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
if (bSuccess)
{
result = Common.RunCmdLine("netsh firewall set portopening tcp 8443 MirthConnectServer ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
}
if (bSuccess)
{
result = Common.RunCmdLine("netsh firewall set portopening tcp 1099 MirthConnectJMX ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
}
if (!bSuccess)
{
Common.Log.Error(String.Format("Errors occured opening up ports for '{0}'", MIRTH_SERVICE_NAME));
}
return bSuccess;
}
public bool INSTALL_COMPONENT()
{
Common.PSetupSpwan(GetComponent().TempFileNamesNPath[0], "-q -overwrite");
return true;
}
public bool AFTER_INSTALLING_COMPONENT()
{
if (!Common.ServiceExists(MIRTH_SERVICE_NAME))
{
Common.Log.Error(String.Format("Service '{0}' does not exist. Something went wrong with Setup", MIRTH_SERVICE_NAME));
return false;
}
// Make sure Service is stopped
Common.StopService(MIRTH_SERVICE_NAME);
// # Configure Mirth to work with PostgreSQL, if possible
if (Common.ServiceExists(POSTGRE_SERVICE_NAME))
{
//SetupMirthToUsePostgreSQL("mirthdb", "postgres", "Clinical$1");
}
return true;
}
public bool SUPPORTS_UNINSTALL()
{
return false;
}
public bool BEFORE_UNINSTALLING_COMPONENT()
{
return false;
}
public bool UNINSTALL_COMPONENT()
{
return false;
}
public bool AFTER_UNINSTALLING_COMPONENT()
{
return false;
}
#endregion
#region ISetup Members
public void ComponentLoaded(ref SetupEvents subscribeToDesiredEvents)
{
subscribeToDesiredEvents.Before_Install += new SetupEvents.SetupEvent(subscribeToDesiredEvents_Before_Install);
subscribeToDesiredEvents.After_Install += new SetupEvents.SetupEvent(subscribeToDesiredEvents_After_Install);
subscribeToDesiredEvents.Ending_Setup += new SetupEvents.SetupEvent(subscribeToDesiredEvents_Ending_Setup);
}
void subscribeToDesiredEvents_Ending_Setup()
{
// Make Sure at the end that both Mirth and Postgresql are started
Common.StartService(POSTGRE_SERVICE_NAME);
Common.StartService(MIRTH_SERVICE_NAME);
}
void subscribeToDesiredEvents_Before_Install()
{
}
void subscribeToDesiredEvents_After_Install()
{
}
#endregion
#region Private Helpers
/// <summary>
/// Function is responsible fore writing Postgresql Information to the Mirth Configuration
/// * The Mirth Service needs to be stopped/started for this configuration to take affect,
/// ideally this should only be called with the mirth service stopped *
/// </summary>
private void SetupMirthToUsePostgreSQL(string dbname, string user, string password)
{
// Open Mirth Configuration
LineReplacer replacer = new LineReplacer((Common.GetProgramFilesPathOnSystemWithEndSlash() + "Mirth Connect\\conf\\mirth.properties"), Encoding.ASCII);
LineReplace_Rule DBurl = new LineReplace_Rule();
DBurl.StartsWith = "database.url =";
DBurl.ReplaceLineWith = String.Format("database.url = jdbc:postgresql://localhost:5432/{0}", dbname);
DBurl.Comparer = LineReplace_ComparerModifier.None;
replacer.AddUpdateRule("DBurl", DBurl);
LineReplace_Rule DBuser = new LineReplace_Rule();
DBuser.StartsWith = "database.username =";
DBuser.ReplaceLineWith = String.Format("database.username = {0}", user);
DBuser.Comparer = LineReplace_ComparerModifier.None;
replacer.AddUpdateRule("DBuser", DBuser);
LineReplace_Rule DBpass = new LineReplace_Rule();
DBpass.StartsWith = "database.password =";
DBpass.ReplaceLineWith = String.Format("database.password = {0}", password);
DBpass.Comparer = LineReplace_ComparerModifier.None;
replacer.AddUpdateRule("DBpass", DBpass);
// Replace Lines in Mirth Configuration
replacer.ReplaceLines();
}
#endregion
}
}

View File

@@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Component.All;
using Microsoft.Win32;
namespace Component.Binary.Java
{
public class InstallComponent : IInstallComponent , ISetup
{
#region IInstallComponent Members
/// <summary>
/// Get the Component bound to this IInstallComponent
/// </summary>
/// <returns></returns>
public ComponentConfig.Component GetComponent()
{
return Common.EmbeddedConfig.BinaryComponents.GetComponent("Java");
}
/// <summary>
/// We only want to install Java if an earlier version is installed
/// </summary>
/// <returns>true, if an earlier version or none is installed, false otherwise</returns>
public bool BEFORE_INSTALLING_COMPONENT()
{
// If we get here, just in case always just install the java version
// to make sure everything works as expected
//string Version = GetLatestJavaVersionFromTheRegistry();
//if (!String.IsNullOrEmpty(Version))
//{
// int nCompare = String.Compare(Version, GetComponent().Version);
// if (nCompare < 0)
// return true;
// else
// return false;
//}
return true;
}
/// <summary>
/// Installs Java on the system
/// </summary>
/// <returns>Returns true if the Component installs, false otherwise</returns>
public bool INSTALL_COMPONENT()
{
Common.PSetupSpwan(GetComponent().TempFileNamesNPath[0], "/s /v \"/qn ADDLOCAL=ALL IEXPLORER=1 REBOOT=Supress\"");
return true;
}
/// <summary>
/// Make sure that the version in the registry matches the component
/// </summary>
/// <returns>true, if the version in the registry matches what we installed, false otherwise</returns>
public bool AFTER_INSTALLING_COMPONENT()
{
string Version = GetLatestJavaVersionFromTheRegistry();
if (!String.IsNullOrEmpty(Version))
{
int nCompare = String.Compare(GetComponent().Version, Version);
if (nCompare != 0)
return false;
else
return true;
}
return false;
}
/// <summary>
/// Check to see, if this component supports uninstalling
/// </summary>
/// <returns>true, if uninstall is supported, false otherwise</returns>
public bool SUPPORTS_UNINSTALL()
{
return true;
}
/// <summary>
/// Check if we can uninstall the java version
/// </summary>
/// <returns>true, if version is installed, false otherwise</returns>
public bool BEFORE_UNINSTALLING_COMPONENT()
{
string[] Versions = GetAllJavaVersionFromTheRegistry();
if (Versions != null && Versions.Length > 0)
{
if (Versions.Contains(GetComponent().Version))
return true;
}
return false;
}
/// <summary>
/// Uninstalls Java on the system
/// </summary>
/// <returns>Returns true if the Component installs, false otherwise</returns>
public bool UNINSTALL_COMPONENT()
{
Common.PSetupSpwan(GetComponent().TempFileNamesNPath[0], "/s /v \"/qn REBOOT=Supress\" /x");
return true;
}
/// <summary>
/// Check to make sure that the version we uninstalled doesn't exist anymore
/// </summary>
/// <returns>true if version was removed, false otherwise</returns>
public bool AFTER_UNINSTALLING_COMPONENT()
{
string[] Versions = GetAllJavaVersionFromTheRegistry();
if (Versions != null && Versions.Length > 0)
{
if (Versions.Contains(GetComponent().Version))
return false;
}
return true;
}
#endregion
#region ISetup Members
public void ComponentLoaded(ref SetupEvents subscribeToDesiredEvents)
{
subscribeToDesiredEvents.Before_Install += new SetupEvents.SetupEvent(subscribeToDesiredEvents_Before_Install);
subscribeToDesiredEvents.After_Install += new SetupEvents.SetupEvent(subscribeToDesiredEvents_After_Install);
}
void subscribeToDesiredEvents_Before_Install()
{
}
void subscribeToDesiredEvents_After_Install()
{
}
#endregion
#region Private Helpers
/// <summary>
/// Use this function to check the java version in the registry
/// </summary>
/// <returns>The Java Version found in the registry or String.Empty, if not found</returns>
string GetLatestJavaVersionFromTheRegistry()
{
string[] Versions = GetAllJavaVersionFromTheRegistry();
if (Versions != null && Versions.Length > 0)
{
string strVersion = Versions[Versions.Length - 1];
if (!String.IsNullOrEmpty(strVersion))
return strVersion;
}
return String.Empty;
}
/// <summary>
/// Use this function to check all the java versions in the registry
/// </summary>
/// <returns>The Java Versions found in the registry or null, if none found</returns>
string[] GetAllJavaVersionFromTheRegistry()
{
bool bIsJavaInstalled = false;
try
{
RegistryKey reg = Registry.LocalMachine.OpenSubKey("Software\\JavaSoft\\Java Plug-in", false);
bIsJavaInstalled = (reg != null);
if(reg == null)
reg = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\JavaSoft\\Java Plug-in", false);
bIsJavaInstalled = (reg != null);
if (bIsJavaInstalled)
{
string[] SubKeys = reg.GetSubKeyNames();
if (SubKeys != null && SubKeys.Length > 0)
return SubKeys;
}
}
catch (Exception) { /* ignore */ }
return null;
}
#endregion
}
}

View File

@@ -0,0 +1,254 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Component.All;
using Microsoft.Win32;
using BridgeConnector.Lib.Assembly;
using System.IO;
using BridgeConnector.Lib.XML;
using BridgeConnector;
namespace Component.Setup.BridgeService
{
public class InstallComponent : IInstallComponent , ISetup
{
#region Private Helpers
public const string BRIDGE_SERVICE_TITLE = Common_MediLytec.MediLytecPoundDef.BRIDGE_SERVICE_TITLE;
public const string BRIDGE_SERVICE_ASSEMBLY = Common_MediLytec.MediLytecPoundDef.BRIDGE_SERVICE_ASSEMBLY;
public const string BRIDGE_SERVICE_NAME = Common_MediLytec.MediLytecPoundDef.BRIDGE_SERVICE_NAME;
/// <summary>
/// Write Service Configuration to the ImagePath for the Service
/// </summary>
/// <returns></returns>
public static bool WriteServiceConfigurationToServiceInRegistry(InstallConfig config)
{
try
{
using (RegistryKey service = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\services\\" + BRIDGE_SERVICE_TITLE, true))
{
// # Determine Image Path Parameter
string ImagePathParameter = "";
switch (config)
{
case InstallConfig.LytecMD:
ImagePathParameter = " /Lytec";
break;
case InstallConfig.MedisoftClinical:
ImagePathParameter = " /Medisoft";
break;
}
// # Set Image Path Parameter
string serviceAssembly = "\"" + AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Executing) + "\\" + BRIDGE_SERVICE_ASSEMBLY + "\"";
service.SetValue("ImagePath", serviceAssembly + ImagePathParameter);
return true;
}
}
catch (Exception) { /* ignore */ }
return false;
}
#endregion
#region IInstallComponent Members
public ComponentConfig.Component GetComponent()
{
return Common.EmbeddedConfig.SetupComponents.GetComponent("BridgeService");
}
public bool BEFORE_INSTALLING_COMPONENT()
{
// Stop Service BRIDGE_SERVICE_NAME
if (!Common.StopService(BRIDGE_SERVICE_NAME))
{
Common.Log.Error(String.Format("Couldn't stop the {0} Service.", BRIDGE_SERVICE_NAME));
return false;
}
// Read the Service Configuration from the Registry
InstallConfig config = Common_MediLytec.RetrieveInstallConfigFromRegistry();
if (config == InstallConfig.LytecMD)
{
bool bSuccess = false;
string result = Common.RunCmdLine("netsh firewall set portopening tcp 5000 BridgeService_LytecBridgeIn ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
if (bSuccess)
{
result = Common.RunCmdLine("netsh firewall set portopening tcp 5001 BridgeService_LytecMirthOut ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
}
if (bSuccess)
{
return true;
}
else
{
Common.Log.Error(String.Format("Opening up ports for Lytec '{0}' failed", BRIDGE_SERVICE_NAME));
return false;
}
}
else if (config == InstallConfig.MedisoftClinical)
{
bool bSuccess = false;
string result = Common.RunCmdLine("netsh firewall set portopening tcp 7000 BridgeService_MedisoftBridgeIn ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
if (bSuccess)
{
result = Common.RunCmdLine("netsh firewall set portopening tcp 7001 BridgeService_MedisoftMirthOut ENABLE ALL");
bSuccess = result.Contains("successfully") || result.Contains("Ok.") || result.Contains("The service has not been started");
}
if (bSuccess)
{
return true;
}
else
{
Common.Log.Error(String.Format("Opening up ports for Medisoft '{0}' failed", BRIDGE_SERVICE_NAME));
return false;
}
}
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool INSTALL_COMPONENT()
{
// Uninstall Bridge Service, if it exists, and re-install
if (Common.ServiceExists(BRIDGE_SERVICE_NAME))
UNINSTALL_COMPONENT();
string installUtil = Common.GetNetFrameworkUtilFileNameNPathFile("installutil.exe");
string serviceAssembly = AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Entry) + "\\" + BRIDGE_SERVICE_ASSEMBLY;
if (!String.IsNullOrEmpty(installUtil))
{
Common.StopService(BRIDGE_SERVICE_NAME);
string result = Common.RunCmdLine(installUtil + " \"" + serviceAssembly + "\"");
bool bSuccess = !result.Contains("failed");
if (bSuccess)
{
// Write the Service Configuration to the Registry
InstallConfig config = Common_MediLytec.RetrieveInstallConfigFromRegistry();
bSuccess = WriteServiceConfigurationToServiceInRegistry(config);
}
if (!bSuccess)
{
Common.Log.Error(String.Format("Errors Occured installing {0}.", BRIDGE_SERVICE_NAME));
}
return bSuccess;
}
return false;
}
public bool AFTER_INSTALLING_COMPONENT()
{
// Make sure service exists
if (!Common.ServiceExists(BRIDGE_SERVICE_NAME))
{
Common.Log.Error(String.Format("Service {0} does Not Exist. Install Failed", BRIDGE_SERVICE_NAME));
return false;
}
// Make sure Service is stopped
Common.StopService(BRIDGE_SERVICE_NAME);
return true;
}
public bool SUPPORTS_UNINSTALL()
{
return false;
}
public bool BEFORE_UNINSTALLING_COMPONENT()
{
// Stop Service BRIDGE_SERVICE_NAME
if (!Common.StopService(BRIDGE_SERVICE_NAME))
{
Common.Log.Error(String.Format("Couldn't stop the {0} Service.", BRIDGE_SERVICE_NAME));
return false;
}
return true;
}
public bool UNINSTALL_COMPONENT()
{
if (Common.ServiceExists(BRIDGE_SERVICE_NAME))
{
Common.StopService(BRIDGE_SERVICE_NAME);
string installUtil = Common.GetNetFrameworkUtilFileNameNPathFile("installutil.exe");
string serviceAssembly = AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Entry) + "\\" + BRIDGE_SERVICE_ASSEMBLY;
if (!String.IsNullOrEmpty(installUtil))
{
string result = Common.RunCmdLine(installUtil + " /u \"" + serviceAssembly + "\"");
bool bSuccess = !result.Contains("failed");
if(!bSuccess)
Common.Log.Error(String.Format("Errors Occured uninstalling {0}.", BRIDGE_SERVICE_NAME));
return bSuccess;
}
}
return false;
}
public bool AFTER_UNINSTALLING_COMPONENT()
{
if (Common.ServiceExists(BRIDGE_SERVICE_NAME))
{
Common.Log.Error(String.Format("Service {0} Still Exists. Uninstall Failed", BRIDGE_SERVICE_NAME));
return false;
}
return true;
}
#endregion
#region ISetup Members
public void ComponentLoaded(ref SetupEvents subscribeToDesiredEvents)
{
subscribeToDesiredEvents.Before_Install += new SetupEvents.SetupEvent(subscribeToDesiredEvents_Before_Install);
subscribeToDesiredEvents.After_Install += new SetupEvents.SetupEvent(subscribeToDesiredEvents_After_Install);
subscribeToDesiredEvents.Ending_Setup += new SetupEvents.SetupEvent(subscribeToDesiredEvents_Ending_Setup);
}
void subscribeToDesiredEvents_Ending_Setup()
{
if (Common.ServiceExists(BRIDGE_SERVICE_NAME))
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\McKesson\\Bridge\\BridgeConfig.xml";
if (File.Exists(path))
{
XSerializer serialize = new XSerializer();
XMLConfig config = serialize.ReadFromFile<XMLConfig>(path);
if (config != null)
{
// Read the Service Configuration from the Registry
InstallConfig sconfig = Common_MediLytec.RetrieveInstallConfigFromRegistry();
if (sconfig == InstallConfig.LytecMD && !String.IsNullOrEmpty(config.DefaultMapping.Lytec))
Common.StartService(BRIDGE_SERVICE_NAME);
else if(sconfig == InstallConfig.MedisoftClinical && !String.IsNullOrEmpty(config.DefaultMapping.Medisoft))
Common.StartService(BRIDGE_SERVICE_NAME);
}
}
}
}
void subscribeToDesiredEvents_Before_Install()
{
}
void subscribeToDesiredEvents_After_Install()
{
}
#endregion
}
}

240
@integrate/Logging.cs Normal file
View File

@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
// Log4Net Declarations
using log4net.Appender;
using log4net.Core;
using log4net.Layout;
using log4net.Config;
using log4net;
using Diag = System.Diagnostics;
using BridgeConnector.Lib.Other;
namespace BridgeConnector.Lib.File
{
/// <summary>
/// Logging Detail
/// </summary>
public enum Logging_Detail
{
NONE,
ERROR,
INFO,
DEBUG
}
/// <summary>
/// Used to Configure a Logger Instance in the Logging Class via AddGlobalLoggerConfiguration()
/// </summary>
public struct Logging_Configuration
{
public string LogFileNameNPath;
public Logging_Detail Detail;
public bool UseExclusiveFileLock;
public int maxFileSizeInMB;
public int numOfBackupLogFiles;
public string PatternLayout;
}
/// <summary>
/// Is a Wrapper Object around Log4Net's Rolling File Appender.
/// Use it by calling AddGlobalLoggerConfiguration() with a valid Logging Configuration.
/// You can configure multipe Logger Instances distinguished by Name.
/// subsequent calls can call GetLogger() with the named Logger instance to receive a valid logger object
/// </summary>
public class Logging
{
#region Private Static Members
private static Dictionary<string, Logging_Configuration> _loggerConfigurationMap = new Dictionary<string, Logging_Configuration>();
private static Dictionary<string, ILog> _loggerObjects = new Dictionary<string, ILog>();
private static bool s_IsVSHosted = false;
#endregion
#region Private Construction
private Logging() { s_IsVSHosted = Diag.Process.GetCurrentProcess().ProcessName.Contains("vshost"); }
#endregion
#region Internal Members
internal ILog _Log4NetLog = null; // Initialized by GetLogger()
#endregion
#region Public Log Methods
public void Info(object message) { if (_Log4NetLog != null) _Log4NetLog.Info(MessageHeader() + message); }
public void Info(object message, int nPlusMinus) { if (_Log4NetLog != null) _Log4NetLog.Info(MessageHeader(nPlusMinus) + message); }
public void Info(object message, Exception exception) { if (_Log4NetLog != null) _Log4NetLog.Info(MessageHeader() + message, exception); }
public void Debug(object message) { if (_Log4NetLog != null) _Log4NetLog.Debug(MessageHeader() + message); }
public void Debug(object message, int nPlusMinus) { if (_Log4NetLog != null) _Log4NetLog.Debug(MessageHeader(nPlusMinus) + message); }
public void Debug(object message, Exception exception) { if (_Log4NetLog != null) _Log4NetLog.Debug(MessageHeader() + message, exception); }
public void Error(object message) { if (_Log4NetLog != null) _Log4NetLog.Error(MessageHeader() + message); }
public void Error(object message, int nPlusMinus) { if (_Log4NetLog != null) _Log4NetLog.Error(MessageHeader(nPlusMinus) + message); }
public void Error(object message, Exception exception) { if (_Log4NetLog != null) _Log4NetLog.Error(MessageHeader() + message, exception); }
public void Fatal(object message) { if (_Log4NetLog != null) _Log4NetLog.Fatal(MessageHeader() + message); }
public void Fatal(object message, int nPlusMinus) { if (_Log4NetLog != null) _Log4NetLog.Fatal(MessageHeader(nPlusMinus) + message); }
public void Fatal(object message, Exception exception) { if (_Log4NetLog != null) _Log4NetLog.Fatal(MessageHeader() + message, exception); }
/// <returns>
/// Message Header to be shown on every log message
/// </returns>
private string MessageHeader()
{
if (s_IsVSHosted)
return MessageHeader(0);
else
return StackWalker.GetMethodNameFromStack(-2) + "()- ";
}
/// <returns>
/// Message Header to be shown on every log message
/// </returns>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
private string MessageHeader(int nPlusMinus)
{
// When Running this from via VS it behaves differently then when
// running it outside of it, when running it regularly, each foreach loop
// is it's own stackframe! ~weird but true. Only use the nPlusMinus when not running
// inside VS
if(s_IsVSHosted)
return StackWalker.GetMethodNameFromStack(nPlusMinus) + "()- ";
else
return StackWalker.GetMethodNameFromStack(nPlusMinus - 1) + "()- ";
}
#endregion
#region Public Static Configuration and Logger Creation Methods
/// <summary>
/// Used to add a new Configuration and Logger Instance onto a Static Map.
/// Will create one logger instance per unique name.
/// </summary>
/// <param name="Name">a name for the logger instance</param>
/// <param name="Configuration">a valid configuration to use on the instance</param>
/// <returns>a logging object that can be used to log</returns>
public static Logging AddGlobalLoggerConfiguration(string Name, Logging_Configuration Configuration)
{
// Must have a Valid Input
if (string.IsNullOrEmpty(Name))
throw new ArgumentException("Name Is Invalid");
if (!_loggerObjects.Keys.Contains(Name.ToLower()))
{
// Create the Repository
log4net.Repository.ILoggerRepository repository = LogManager.CreateRepository(Name.ToLower());
// Create FileAppender Configuration
RollingFileAppender appender = RollingFileAppenderCreator(Configuration);
// Run the Configuration against the Repository
BasicConfigurator.Configure(repository, appender);
// Add Configuration to our Static Map
_loggerConfigurationMap[Name.ToLower()] = Configuration;
// Last, but not least, Create the new Logging Instance Object and Store it
_loggerObjects[Name.ToLower()] = LogManager.GetLogger(Name.ToLower(), Name.ToLower());
}
// Let the Caller get the Logging Object
return GetLogger(Name);
}
/// <summary>
/// Used to retrieve a named logging instance that has already been created via a previous call
/// to AddGlobalLoggerConfiguration().
/// </summary>
/// <param name="Name">a name for a previously created Logging instance</param>
/// <returns>a Logging object that can be used to log</returns>
public static Logging GetLogger(string Name)
{
if (_loggerObjects.Keys.Contains(Name.ToLower()))
{
Logging logger = new Logging();
logger._Log4NetLog = _loggerObjects[Name.ToLower()];
return logger;
}
else
throw new ArgumentException("Must call AddGlobalLoggerConfiguration() with a Configuration Before calling this Function");
}
#endregion
#region Private Static Helper Methods
/// <summary>
/// Creates a Log4Net RollingFileAppender with the specified configuration
/// </summary>
/// <param name="config">a valid configuration</param>
/// <returns>a Log4Net RollingFileAppender Object</returns>
private static RollingFileAppender RollingFileAppenderCreator(Logging_Configuration config)
{
#region Input Validation
if (config.maxFileSizeInMB <= 0)
throw new ArgumentException("Logging_Configuration - Invalid maxFileSizeInMB");
if (config.numOfBackupLogFiles < 0)
throw new ArgumentException("Logging_Configuration - Invalid numOfBackupLogFiles");
if (String.IsNullOrEmpty(config.LogFileNameNPath))
throw new Exception("Logging_Configuration - Invalid LogFileNameNPath");
if (!Directory.Exists(Path.GetDirectoryName(config.LogFileNameNPath)))
Directory.CreateDirectory(Path.GetDirectoryName(config.LogFileNameNPath));
#endregion
// Create and Set Layout for FileAppender
RollingFileAppender rfAppender = new RollingFileAppender();
if (!String.IsNullOrEmpty(config.PatternLayout))
rfAppender.Layout = new PatternLayout(config.PatternLayout);
else
rfAppender.Layout = new PatternLayout("%date{dd MMM HH:mm:ss,fff} [%thread] %level - %message%newline");
//rfAppender.Layout = new PatternLayout("%date{dd MMM yyyy HH:mm:ss,fff} [%thread] %level %logger - %message%newline");
// Locking Minimal allows us to run Log4Net from multiple processes
if (config.UseExclusiveFileLock)
rfAppender.LockingModel = new FileAppender.ExclusiveLock();
else
rfAppender.LockingModel = new FileAppender.MinimalLock();
// Configure FileName and always set Appent to true
rfAppender.File = config.LogFileNameNPath;
rfAppender.AppendToFile = true;
// According to the listings on the blog site
// http://blog.aggregatedintelligence.com/2009/08/log4net-logging-levels-available.html
// Error, will log Error, Fatal
// Info, will log Info, Error, and Fatal
// Debug, will log Info, Error, Fatal and Debug
if (config.Detail == Logging_Detail.NONE)
rfAppender.Threshold = Level.Off;
else if (config.Detail == Logging_Detail.ERROR)
rfAppender.Threshold = Level.Error;
else if (config.Detail == Logging_Detail.INFO)
rfAppender.Threshold = Level.Info;
else if (config.Detail == Logging_Detail.DEBUG)
rfAppender.Threshold = Level.Debug;
rfAppender.MaximumFileSize = String.Format("{0}MB", config.maxFileSizeInMB);
rfAppender.MaxSizeRollBackups = config.numOfBackupLogFiles;
rfAppender.RollingStyle = RollingFileAppender.RollingMode.Size; // Setting to RollingMode.Size will make MaxSizeRollBackups work
rfAppender.ActivateOptions();
return rfAppender;
}
#endregion
}
}

482
@integrate/MsgBox.cs Normal file
View File

@@ -0,0 +1,482 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Watchdog.WatchdogLib.Win32;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using WPFWin = System.Windows;
using WPFWinInterop = System.Windows.Interop;
namespace Watchdog.WatchdogLib.WinForms
{
/// <summary>
/// MsgBox is a WindowsForms MessageBox that can be centered to the Parent
/// </summary>
public static class MsgBox
{
#region Private Static Members
private static User32.WindowsHookProc _hookProcDelegate = null;
private static int _hHook = 0;
private static string _title = null;
private static string _msg = null;
private static IntPtr _hIcon = IntPtr.Zero;
private static bool _IsDesktopOwner = false;
private static bool _ShowFatal = false;
// Delegate to make All Message Boxes Thread-Safe
private delegate DialogResult ShowMsgBoxDelegate(IWin32Window parent, String Title, String Text, MessageBoxButtons MsgBoxButtons, MessageBoxIcon MsgBoxIcon, Icon TitleBarIcon);
#endregion
#region Public Properties
public static Icon DefaultTitleBarIcon { get; set; }
public static uint MaxNumberOfCharactersPerLine { get; set; }
public const uint DefaultNumberOfCharactersPerLine = 62;
#endregion
#region Public Header Properties
public static bool ShowHeader { get; set; }
public static string MsgBox_ErrorHeader { get; set; }
public static string MsgBox_FatalErrorHeader { get; set; }
public static string MsgBox_WarningHeader { get; set; }
public static string MsgBox_InfoHeader { get; set; }
#endregion
#region Public Footer Properties
public static bool ShowFooter { get; set; }
public static string MsgBox_ErrorFooter { get; set; }
public static string MsgBox_FatalErrorFooter { get; set; }
public static string MsgBox_WarningFooter { get; set; }
public static string MsgBox_InfoFooter { get; set; }
#endregion
#region Public Title Header Properties
public static bool ShowTitleHeader { get; set; }
public static string MsgBox_ErrorTitleHeader { get; set; }
public static string MsgBox_FatalErrorTitleHeader { get; set; }
public static string MsgBox_WarningTitleHeader { get; set; }
public static string MsgBox_InfoTitleHeader { get; set; }
#endregion
#region Construction
static MsgBox()
{
DefaultTitleBarIcon = null;
MaxNumberOfCharactersPerLine = DefaultNumberOfCharactersPerLine;
// Header Init
MsgBox_FatalErrorHeader = String.Empty;
MsgBox_ErrorHeader = String.Empty;
MsgBox_WarningHeader = String.Empty;
MsgBox_InfoHeader = String.Empty;
ShowHeader = true;
// Footer Init
MsgBox_FatalErrorFooter = String.Empty;
MsgBox_ErrorFooter = String.Empty;
MsgBox_WarningFooter = String.Empty;
MsgBox_InfoFooter = String.Empty;
ShowFooter = true;
// Title Header Init
MsgBox_FatalErrorTitleHeader = String.Empty;
MsgBox_ErrorTitleHeader = String.Empty;
MsgBox_WarningTitleHeader = String.Empty;
MsgBox_InfoTitleHeader = String.Empty;
ShowTitleHeader = true;
}
#endregion
#region Public Static Methods
/// <summary>
/// Shows a custom Message Box (centered to parent), with the DefaultTitleBarIcon
/// </summary>
public static DialogResult Show(WPFWin.Window parent, String Title, String Text, MessageBoxButtons MsgBoxButtons, MessageBoxIcon MsgBoxIcon)
{
if (parent != null)
{
WPFWinInterop.WindowInteropHelper interop = new WPFWinInterop.WindowInteropHelper(parent);
if(interop.Handle != IntPtr.Zero)
return Show(Watchdog.WatchdogLib.Win32.Convert.ConverthWndToIWin32Window(interop.Handle), Title, Text, MsgBoxButtons, MsgBoxIcon, DefaultTitleBarIcon);
}
return Show(Functions.GetDestopWindow(), Title, Text, MsgBoxButtons, MsgBoxIcon, DefaultTitleBarIcon);
}
/// <summary>
/// Shows a custom Message Box (centered to parent), with the DefaultTitleBarIcon
/// </summary>
public static DialogResult Show(IWin32Window parent, String Title, String Text, MessageBoxButtons MsgBoxButtons, MessageBoxIcon MsgBoxIcon)
{
return Show(parent, Title, Text, MsgBoxButtons, MsgBoxIcon, DefaultTitleBarIcon);
}
/// <summary>
/// Shows a custom Message Box (centered to Desktop), with the DefaultTitleBarIcon
/// </summary>
public static DialogResult Show(String Title, String Text, MessageBoxButtons MsgBoxButtons, MessageBoxIcon MsgBoxIcon)
{
return Show(Functions.GetDestopWindow(), Title, Text, MsgBoxButtons, MsgBoxIcon, DefaultTitleBarIcon);
}
/// <summary>
/// *Main MessageBox Show Function* allows you to center the Message Box to the Parent
/// </summary>
/// <returns>Result of Dialog </returns>
public static DialogResult Show(IWin32Window parent, String Title, String Text, MessageBoxButtons MsgBoxButtons, MessageBoxIcon MsgBoxIcon, Icon TitleBarIcon)
{
ISynchronizeInvoke InvokeObject = null;
if (parent != null && parent is ISynchronizeInvoke)
InvokeObject = (ISynchronizeInvoke)parent;
// Invoke if we need to * Make MessageBoxes generally Thread-safe *
if ((InvokeObject != null) && InvokeObject.InvokeRequired)
{
DialogResult result = (DialogResult)InvokeObject.Invoke(new ShowMsgBoxDelegate(MsgBox.Show), new object[] { parent, Title, Text, MsgBoxButtons, MsgBoxIcon, TitleBarIcon });
return result;
}
else
{
return MsgBox.ShowInternal(parent, Text, Title, MsgBoxButtons, MsgBoxIcon, TitleBarIcon);
}
}
#endregion
#region Public Static Methods Extended
/// <summary>
/// Shows Warning MessageBox
/// </summary>
//public static DialogResult ShowWarning(IWin32Window parent, String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowWarning(IWin32Window parent, String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(parent, Title, Text, MsgBoxButtons, MessageBoxIcon.Exclamation);
}
/// <summary>
/// Shows Warning MessageBox
/// </summary>
//public static DialogResult ShowWarning(String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowWarning(String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(Title, Text, MsgBoxButtons, MessageBoxIcon.Exclamation);
}
/// <summary>
/// Shows Fatal Error MessageBox
/// </summary>
//public static DialogResult ShowFatalError(IWin32Window parent, String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowFatalError(IWin32Window parent, String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
_ShowFatal = true;
DialogResult dr = Show(parent, Title, Text, MsgBoxButtons, MessageBoxIcon.Error);
_ShowFatal = false;
return dr;
}
/// <summary>
/// Shows Fatal Error MessageBox
/// </summary>
//public static DialogResult ShowFatalError(String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowFatalError(String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
_ShowFatal = true;
DialogResult dr = Show(Title, Text, MsgBoxButtons, MessageBoxIcon.Error);
_ShowFatal = false;
return dr;
}
/// <summary>
/// Shows Error MessageBox
/// </summary>
//public static DialogResult ShowError(IWin32Window parent, String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowError(IWin32Window parent, String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(parent, Title, Text, MsgBoxButtons, MessageBoxIcon.Error);
}
/// <summary>
/// Shows Error MessageBox
/// </summary>
//public static DialogResult ShowError(String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowError(String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(Title, Text, MsgBoxButtons, MessageBoxIcon.Error);
}
/// <summary>
/// Shows Information MessageBox
/// </summary>
//public static DialogResult ShowInfo(IWin32Window parent, String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowInfo(IWin32Window parent, String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(parent, Title, Text, MsgBoxButtons, MessageBoxIcon.Information);
}
/// <summary>
/// Shows Information MessageBox
/// </summary>
//public static DialogResult ShowInfo(String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowInfo(String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(Title, Text, MsgBoxButtons, MessageBoxIcon.Information);
}
/// <summary>
/// Shows Default MessageBox
/// </summary>
//public static DialogResult ShowDefault(IWin32Window parent, String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowDefault(IWin32Window parent, String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(parent, Title, Text, MsgBoxButtons, MessageBoxIcon.None);
}
/// <summary>
/// Shows Default MessageBox
/// </summary>
//public static DialogResult ShowDefault(String Text, String Title = "", MessageBoxButtons MsgBoxButtons = MessageBoxButtons.OK)
public static DialogResult ShowDefault(String Text, String Title, MessageBoxButtons MsgBoxButtons)
{
return Show(Title, Text, MsgBoxButtons, MessageBoxIcon.None);
}
#endregion
#region Private Methods
/// <summary>
///
/// </summary>
/// <param name="owner"></param>
/// <param name="msg"></param>
/// <param name="title"></param>
/// <param name="btns"></param>
/// <param name="icon"></param>
/// <param name="TitleBarIcon"></param>
/// <returns></returns>
private static DialogResult ShowInternal(IWin32Window owner, string msg, string title, MessageBoxButtons btns, MessageBoxIcon icon, Icon TitleBarIcon)
{
// Create a callback delegate
_hookProcDelegate = new User32.WindowsHookProc(HookCallback);
#region Header Action
if (ShowHeader)
{
if (icon == MessageBoxIcon.Error && !String.IsNullOrEmpty(MsgBox_FatalErrorHeader) && _ShowFatal)
msg = MsgBox_FatalErrorHeader + msg;
else if (icon == MessageBoxIcon.Error && !String.IsNullOrEmpty(MsgBox_ErrorHeader) && !_ShowFatal)
msg = MsgBox_ErrorHeader + msg;
else if (icon == MessageBoxIcon.Exclamation && !String.IsNullOrEmpty(MsgBox_WarningHeader))
msg = MsgBox_WarningHeader + msg;
else if (icon == MessageBoxIcon.Information && !String.IsNullOrEmpty(MsgBox_InfoHeader))
msg = MsgBox_InfoHeader + msg;
}
#endregion
#region Footer Action
if (ShowFooter)
{
if (icon == MessageBoxIcon.Error && !String.IsNullOrEmpty(MsgBox_FatalErrorFooter) && _ShowFatal)
msg = msg + MsgBox_FatalErrorFooter;
else if (icon == MessageBoxIcon.Error && !String.IsNullOrEmpty(MsgBox_ErrorFooter) && !_ShowFatal)
msg = msg + MsgBox_ErrorFooter;
else if (icon == MessageBoxIcon.Exclamation && !String.IsNullOrEmpty(MsgBox_WarningFooter))
msg = msg + MsgBox_WarningFooter;
else if (icon == MessageBoxIcon.Information && !String.IsNullOrEmpty(MsgBox_InfoFooter))
msg = msg + MsgBox_InfoFooter;
}
#endregion
#region Title Header
if (ShowTitleHeader)
{
if (icon == MessageBoxIcon.Error && !String.IsNullOrEmpty(MsgBox_FatalErrorTitleHeader) && _ShowFatal)
title = MsgBox_FatalErrorTitleHeader + ((!String.IsNullOrEmpty(title)) ? (" (" + title + ")") : "");
else if (icon == MessageBoxIcon.Error && !String.IsNullOrEmpty(MsgBox_ErrorTitleHeader) && !_ShowFatal)
title = MsgBox_ErrorTitleHeader + ((!String.IsNullOrEmpty(title)) ? (" (" + title + ")") : "");
else if (icon == MessageBoxIcon.Exclamation && !String.IsNullOrEmpty(MsgBox_WarningTitleHeader))
title = MsgBox_WarningTitleHeader + ((!String.IsNullOrEmpty(title)) ? (" (" + title + ")") : "");
else if (icon == MessageBoxIcon.Information && !String.IsNullOrEmpty(MsgBox_InfoTitleHeader))
title = MsgBox_InfoTitleHeader + ((!String.IsNullOrEmpty(title)) ? (" (" + title + ")") : "");
}
#endregion
#region Text Padding
// Stripe last \n, if exists
if (!String.IsNullOrEmpty(msg) && (msg.Length > 0) && (msg[msg.Length - 1] == '\n'))
msg = msg.Remove(msg.Length - 1);
// Make sure the text looks good, by using padding
if (!String.IsNullOrEmpty(msg) && (msg.Length > 0) && (msg.Length < MaxNumberOfCharactersPerLine))
{
string[] lines = msg.Split('\n');
StringBuilder sb = new StringBuilder();
foreach (string line in lines)
{
sb.Append(line.PadRight((int)MaxNumberOfCharactersPerLine));
sb.Append("\n");
}
msg = sb.ToString();
}
else if (!String.IsNullOrEmpty(msg) && (msg.Length > 0) && (msg.Length > MaxNumberOfCharactersPerLine))
{
// Incredible and amazing Padding code
string[] lines = msg.Split('\n');
StringBuilder sb = new StringBuilder();
for (int i = 0; i < lines.Length; ++i)
{
if (lines[i].Length < MaxNumberOfCharactersPerLine)
{
sb.Append(lines[i].PadRight((int)MaxNumberOfCharactersPerLine));
sb.Append("\n");
}
else if (lines[i].Length > MaxNumberOfCharactersPerLine)
{
// truncate
for (int j = 0; j < lines[i].Length; j = j + (int)MaxNumberOfCharactersPerLine)
{
string strSub = lines[i].Substring(j, ((lines[i].Length - j) > (int)MaxNumberOfCharactersPerLine) ? (int)MaxNumberOfCharactersPerLine : (lines[i].Length - j));
if (strSub.Length == (int)MaxNumberOfCharactersPerLine)
{
sb.Append(strSub);
sb.Append("\n");
}
else
{
sb.Append(strSub.PadRight((int)MaxNumberOfCharactersPerLine));
sb.Append("\n");
}
}
}
else
{
sb.Append(lines[i]);
sb.Append("\n");
}
}
// Write nicely formatted Message out
msg = sb.ToString();
}
else
{
// do nothing, string is miracioulsy exactly correct
}
#endregion
// Remember the title & message that we'll look for.
// The hook sees *all* windows, so we need to make sure we operate on the right one.
_msg = msg;
_title = title;
// if Owner is the Desktop Window
_IsDesktopOwner = (owner.Handle == Functions.GetDestopWindow().Handle);
// Icon could not be present
if (TitleBarIcon != null)
_hIcon = TitleBarIcon.ToBitmap().GetHicon();
// Set the hook.
// Suppress "GetCurrentThreadId() is deprecated" warning.
// It's documented that Thread.ManagedThreadId doesn't work with SetWindowsHookEx()
#pragma warning disable 0618
_hHook = User32.SetWindowsHookEx(Definitions.WH_CBT, _hookProcDelegate, IntPtr.Zero, AppDomain.GetCurrentThreadId());
#pragma warning restore 0618
// Pop a standard MessageBox. The hook will center it.
DialogResult rslt = DialogResult.None;
if (_IsDesktopOwner)
rslt = MessageBox.Show(_msg, _title, btns, icon);
else
rslt = MessageBox.Show(owner, _msg, _title, btns, icon);
// Release hook, clean up (may have already occurred)
Unhook();
return rslt;
}
private static void Unhook()
{
User32.UnhookWindowsHookEx(_hHook);
_hHook = 0;
_hookProcDelegate = null;
_msg = null;
_title = null;
}
private static int HookCallback(int code, IntPtr wParam, IntPtr lParam)
{
int hHook = _hHook; // Local copy for CallNextHookEx() JIC we release _hHook
// Look for HCBT_ACTIVATE, *not* HCBT_CREATEWND:
// child controls haven't yet been created upon HCBT_CREATEWND.
if (code == Definitions.HCBT_ACTIVATE)
{
string cls = Functions.GetWindowClassName(wParam);
if (cls == "#32770") // MessageBoxes are Dialog boxes
{
string title = Functions.GetWindowText(wParam);
string msg = Functions.GetDlgItemText(wParam, 0xFFFF); // -1 aka IDC_STATIC
if ((title == _title) && (msg == _msg))
{
// Only Center the Window, if the Owner is NOT the Desktop
if (!_IsDesktopOwner)
CenterWindowOnParent(wParam);
Unhook(); // Release hook - we've done what we needed
// Now we also want to set the Icon on the Dialog
if (_hIcon != IntPtr.Zero)
{
User32.SendMessage(wParam, (int)Definitions.WM.WM_SETICON, (IntPtr)1, _hIcon);
User32.SendMessage(wParam, (int)Definitions.WM.WM_SETICON, (IntPtr)0, _hIcon);
}
}
}
}
return User32.CallNextHookEx(hHook, code, wParam, lParam);
}
// Boilerplate window-centering code.
// Split out of HookCallback() for clarity.
private static void CenterWindowOnParent(IntPtr hChildWnd)
{
// Get child (MessageBox) size
Structures.RECT rcChild = new Structures.RECT();
User32.GetWindowRect(hChildWnd, out rcChild);
int cxChild = rcChild.right - rcChild.left;
int cyChild = rcChild.bottom - rcChild.top;
// Get parent (Form) size & location
IntPtr hParent = User32.GetParent(hChildWnd);
Structures.RECT rcParent = new Structures.RECT();
User32.GetWindowRect(hParent, out rcParent);
int cxParent = rcParent.right - rcParent.left;
int cyParent = rcParent.bottom - rcParent.top;
// Center the MessageBox on the Form
int x = rcParent.left + (cxParent - cxChild) / 2;
int y = rcParent.top + (cyParent - cyChild) / 2;
uint uFlags = 0x15; // SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE;
User32.SetWindowPos(hChildWnd, IntPtr.Zero, x, y, 0, 0, uFlags);
}
#endregion
}
}

12
@integrate/README.txt Normal file
View File

@@ -0,0 +1,12 @@
Things to go over
File->Logging.cs
Process->PStarter.cs
Thread->SingleThreadTimer.cs (new)
Watchdog->SysTray.cs
Watchdog->MsgBox.cs
Watchdog->Timer.cs
Watchdog->Installer.cs (new)
Watchdog->CHMFile.cs (new)

120
@integrate/ResxHelper.cs Normal file
View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using System.Reflection;
using System.IO;
using Watchdog.WatchdogLib.Assembly;
namespace Watchdog
{
// ResxTypes
public enum Resx
{
AppResx,
}
#region ResxHelper Wrapper Classes
/// <summary>
/// AppResx Wrapper String Resource Value Functions
/// </summary>
public static class AppResx
{
public static string GetString(string name)
{
return ResxHelper.GetStringValue(Resx.AppResx, name);
}
public static string GetStringFormated(string name, params object[] args)
{
return ResxHelper.GetStringValueFormated(Resx.AppResx, name, args);
}
}
#endregion
/// <summary>
/// Allows External Callers To Quickly gain access to the Resources Contained in this Assembly
/// </summary>
public static class ResxHelper
{
/// <summary>
/// Private static Dictionary Map of Resource Managers
/// </summary>
private static Dictionary<Resx, ResourceManager> _ResourceMap = new Dictionary<Resx, ResourceManager>();
/// <summary>
/// Static Constructor, iterates through the enumerations and loads resourceManagers internally
/// </summary>
static ResxHelper()
{
//string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
//~we shouldn't be doing this on filename (filename could change)
//string curAsmName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().ManifestModule.Name);
string curAsmName = AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Entry);
// Create a ResourceManager for each Resource Type in this Assembly
foreach (string ResxName in Enum.GetNames(typeof(Resx)))
_ResourceMap.Add((Resx)Enum.Parse(typeof(Resx), ResxName), new ResourceManager((curAsmName + "." + ResxName), Assembly.GetExecutingAssembly()));
}
#region String Resource Value Functions
/// <summary>
/// Returns the Value of a String Resource via GetString()
/// </summary>
/// <param name="resx">Reource Type to Access</param>
/// <param name="Name">Name of String Resource to get</param>
/// <returns>the value of the resource, or "" if not found/Error Occured</returns>
public static string GetStringValue(Resx resx, string Name)
{
try
{
if (!String.IsNullOrEmpty(Name))
{
string Value = PreserverFormating(_ResourceMap[resx].GetString(Name));
return Value;
}
}
catch (Exception) { /* ignore */ }
return String.Empty;
}
/// <summary>
/// Returns a Formated String Value of a String Resource via GetString()
/// </summary>
/// <param name="resx">Reource Type to Access</param>
/// <param name="Name">Name of String Resource to get</param>
/// <param name="args">Arguments to pass into String.Format()</param>
/// <returns>the value of the resource, or "" if not found/Error Occured</returns>
public static string GetStringValueFormated(Resx resx, string Name, params object[] args)
{
String retVal = GetStringValue(resx, Name);
if (!String.IsNullOrEmpty(retVal))
return String.Format(retVal, args);
else
return String.Empty;
}
/// <summary>
/// we want to preserver formating using '\' characters that are in the resource
/// </summary>
/// <param name="Name">a string value retrieved from the resource</param>
/// <returns>a string that preserves formatting</returns>
private static string PreserverFormating(string Value)
{
if (!String.IsNullOrEmpty(Value))
{
Value = Value.Replace("\\N", "\n");
Value = Value.Replace("\\n", "\n");
Value = Value.Replace("\\T", "\t");
Value = Value.Replace("\\t", "\t");
return Value;
}
return String.Empty;
}
#endregion
}
}

1057
@integrate/Settings.cs Normal file

File diff suppressed because it is too large Load Diff

24
@integrate/Snippets.txt Normal file
View File

@@ -0,0 +1,24 @@
private string GetDefaultBrowserPath()
{
try
{
if (ApplicationSettings.appSettings().LogEvents)
{
CrossProductLogging.WriteEventLogFile("Begin GetDefaultBrowserPath");
}
string key = @"htmlfile\shell\open\command";
RegistryKey registryKey =
Registry.ClassesRoot.OpenSubKey(key, false);
// get default browser path
if (ApplicationSettings.appSettings().LogEvents)
{
CrossProductLogging.WriteEventLogFile("End GetDefaultBrowserPath");
}
return ((string)registryKey.GetValue(null, null)).Split('"')[1];
}
catch
{
return "";
}
}

238
@integrate/SysTray.cs Normal file
View File

@@ -0,0 +1,238 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using WatchdogLib.Thread;
using System.Timers;
namespace WatchdogLib.WinForms
{
/// <summary>
/// Wrapper Class around .Net NotifyIcon, to make it easier to work with an System Tray Icon.
/// Instantiate the object and set ContextMenu or ContextMenuStrip in order to have a right click menu.
/// Subscripe to the MouseLeftClick, and MouseLeftDoubleClick event to get accurate events to handle,
/// Call Show()/Hide() to show/hide the System Tray Icon, respectively.
/// </summary>
public class SysTray
{
#region Public Properties
public NotifyIcon trayNotify { get; private set; }
public Icon Icon { get { return trayNotify.Icon; } set { trayNotify.Icon = value; } }
public ContextMenu trayMenu { get { return trayNotify.ContextMenu; } set { trayNotify.ContextMenu = value; } }
public ContextMenuStrip trayMenuStrip { get { return trayNotify.ContextMenuStrip; } set { trayNotify.ContextMenuStrip = value; } }
public string toolTip { get { return trayNotify.Text; } set { trayNotify.Text = value; } }
public bool Visible { get { return trayNotify.Visible; } }
#endregion
#region Public Events
public delegate void SingleLeftMouseClick(MouseEventArgs e);
/// <summary>
/// Subscribe to get the Left Mouse Single Click Event
/// </summary>
public event SingleLeftMouseClick LeftMouseClick;
public delegate void DoubleLeftMouseClick(MouseEventArgs e);
/// <summary>
/// Subscribe to get the Left Mouse Double Click Event
/// </summary>
public event DoubleLeftMouseClick LeftMouseDoubleClick;
public delegate void RightMouseClick(MouseEventArgs e);
/// <summary>
/// Subscribe to get any Right Mouse Fired Event, use to redo context menu, if needed
/// </summary>
public event RightMouseClick RightMouseFired;
#endregion
#region Private Members
private TTimer SingleClickDetectTimer = null;
private TimeSpan _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks);
private const int _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT = 500;
private const int _N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT = 2; // to avoid tripple clicks, etc... (only sends one double click)
/// <summary>
/// Returns true if enough time since _LastFiredEvent has passed
/// </summary>
private bool EnoughTimeSinceLastEventHasElapsed
{
get
{
// 1 second is 10 Million ticks, one Milisecond is 10K
return (DateTime.Now.Ticks - _LastFiredEvent.Ticks) >= (_N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT * 1000 * 10000);
}
}
#endregion
#region Construction
/// <summary>
/// Construct a System Tray Icon (use public properties like ContextMenu,Icon,toolTip to customize further)
/// </summary>
/// <param name="toolTip">pass in an initial ToolTip to display, defaults to ""</param>
/// <param name="icon">if null, defaults to systemIcons.Application</param>
//public SysTray(string toolTip = "", Icon icon = null)
public SysTray(string toolTip, Icon icon)
{
// Create internal objects
this.trayNotify = new NotifyIcon();
this.SingleClickDetectTimer = new TTimer(new ElapsedEventHandler(RealSingleClickDetectTimer_ElapsedEventHandler), _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT, false, true);
// Add Single / Double-Click Event Handlers
trayNotify.Click += new EventHandler(trayNotify_Click);
trayNotify.DoubleClick += new EventHandler(trayNotify_DoubleClick);
trayNotify.MouseDown += new MouseEventHandler(trayNotify_MouseDown);
// Set ToolTip
if (!String.IsNullOrEmpty(toolTip))
this.toolTip = toolTip;
// Set Icon
if (icon == null)
this.Icon = new Icon(SystemIcons.Application, 40, 40);
else
this.Icon = icon;
}
#endregion
#region Click Event Handlers
/// <summary>
/// Called by NotifyIcon DoubleClick Event, We filter for only the left mouse double-click,
/// event and fire event when neccessary
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void trayNotify_DoubleClick(object sender, EventArgs e)
{
MouseEventArgs args = (MouseEventArgs)e;
if (args.Button == MouseButtons.Left)
{
SingleClickDetectTimer.Stop();
if (LeftMouseDoubleClick != null && EnoughTimeSinceLastEventHasElapsed)
{
_LastFiredEvent = new TimeSpan(DateTime.Now.Ticks);
LeftMouseDoubleClick(new MouseEventArgs(MouseButtons.Left, 2, 0, 0, 0));
}
}
}
/// <summary>
// Called by NotifyIcon Click Event, We filter for only the left mouse click,
/// event and fire event when neccessary
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void trayNotify_Click(object sender, EventArgs e)
{
MouseEventArgs args = (MouseEventArgs) e;
if (args.Button == MouseButtons.Left && EnoughTimeSinceLastEventHasElapsed)
SingleClickDetectTimer.Start(); // Start Single Click Detect Timer
}
/// <summary>
/// In order to accurately re-do a context menu, we handle MouseDown for the
/// Right-Mouse click. Mouse Down comes in before the click event, which gives
/// the caller an opportunity to handle/recreate the context menu dynamically, if needed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void trayNotify_MouseDown(object sender, MouseEventArgs e)
{
MouseEventArgs args = (MouseEventArgs)e;
if (args.Button == MouseButtons.Right && (RightMouseFired != null))
RightMouseFired(args);
}
/// <summary>
/// Used to detect ONLY Single Clicks, since a single-click and then a double-click fires,
/// we want to ignore the first click,and first see if a double-click comes in, if so, ignore
/// the single click, otherwise send it. (this is done by trayNotify_Click & transNotify_DoubleClick)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RealSingleClickDetectTimer_ElapsedEventHandler(object sender, ElapsedEventArgs e)
{
SingleClickDetectTimer.Stop();
if (LeftMouseClick != null)
{
_LastFiredEvent = new TimeSpan(DateTime.Now.Ticks);
LeftMouseClick(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
}
}
#endregion
#region Show N' Hide
/// <summary>
/// Show the System Tray Icon
/// </summary>
public void Show()
{
trayNotify.Visible = true;
}
/// <summary>
/// Hide the System Tray Icon
/// </summary>
public void Hide()
{
trayNotify.Visible = false;
}
#endregion
#region Public ShowBallon
/// <summary>
/// Pops up a Ballon over the System Tray Icon
/// </summary>
/// <param name="nTimeoutInSeconds">Specify the Timeout in Seconds</param>
//public void ShowBallon_Default(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Default(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.None);
}
/// <summary>
/// Pops up a Error Ballon over the System Tray Icon
/// </summary>
/// <param name="nTimeoutInSeconds">Specify the Timeout in Seconds</param>
//public void ShowBallon_Error(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Error(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.Error);
}
/// <summary>
/// Pops up a Warning Ballon over the System Tray Icon
/// </summary>
/// <param name="nTimeoutInSeconds">Specify the Timeout in Seconds</param>
//public void ShowBallon_Warning(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Warning(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.Warning);
}
/// <summary>
/// Pops up a Info Ballon over the System Tray Icon
/// </summary>
/// <param name="nTimeoutInSeconds">Specify the Timeout in Seconds</param>
//public void ShowBallon_Info(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Info(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.Info);
}
#endregion
}
}

140
@integrate/TTimer.cs Normal file
View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Windows.Threading;
using WinThread = System.Threading;
namespace WatchdogLib.Thread
{
/// <summary>
/// Wrapper class around Timer Objects
/// </summary>
public class TTimer : IDisposable
{
// private Members
private Timer _Timer = new Timer();
private bool _disposed = false;
private Dispatcher _Dispatcher = null;
private ElapsedEventHandler _DispatchedElapsedEvent = null;
/// <summary>
/// Creates a new Multi-threaded System.Timer
/// </summary>
/// <param name="ElapsedHandler">Event Handler for Timer</param>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
//public TTimer(ElapsedEventHandler ElapsedHandler, int IntervalMiliseconds = 1000, bool StartEnabled = false, bool bUseDispatcher = true)
public TTimer(ElapsedEventHandler ElapsedHandler, int IntervalMiliseconds, bool StartEnabled, bool bUseDispatcher)
{
if (ElapsedHandler != null)
{
_Timer = new System.Timers.Timer();
// The Primary Dispatcher thread is the thread that called us
if (bUseDispatcher)
{
_Dispatcher = Dispatcher.CurrentDispatcher;
_DispatchedElapsedEvent = ElapsedHandler;
_Timer.Elapsed += new ElapsedEventHandler(_Timer_Elapsed);
}
else
{
_Timer.Elapsed += ElapsedHandler;
}
// Set the Interval / start
_Timer.Interval = IntervalMiliseconds;
_Timer.Enabled = StartEnabled;
if (StartEnabled)
_Timer.Start();
// Keep the timer alive
GC.KeepAlive(_Timer);
}
}
/// <summary>
/// For Dispatching the Event to the Primary Dispatcher Thread
/// </summary>
void _Timer_Elapsed(object sender, ElapsedEventArgs e)
{
object[] param_s = new object[] { sender, e };
_Dispatcher.Invoke((ElapsedEventHandler)_DispatchedElapsedEvent, param_s);
}
/// <summary>
/// Manually Start the Timer
/// </summary>
public void Start()
{
Stop(); // First Stop(), an existing Timer
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Start the Timer at a new Interval
/// </summary>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
public void Start(uint IntervalMiliseconds)
{
Stop(); // First Stop(), an existing Timer
_Timer.Interval = IntervalMiliseconds;
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Start the Timer at a new Interval
/// </summary>
/// <param name="tsInterval">Interval as a TimeSpan</param>
public void Start(TimeSpan tsInterval)
{
Stop(); // First Stop(), an existing Timer
_Timer.Interval = tsInterval.TotalMilliseconds;
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Stop the Timer
/// </summary>
public void Stop()
{
_Timer.Enabled = false;
_Timer.Stop();
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (_Timer != null)
_Timer.Dispose();
}
// Indicate that the instance has been disposed.
_Timer = null;
_disposed = true;
}
}
#endregion
}
}

View File

@@ -0,0 +1,654 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Security;
using System.Security.Permissions;
namespace Trinet.Core.IO.Ntfs
{
/// <summary>
/// Represents the details of an alternative data stream.
/// </summary>
[DebuggerDisplay("{FullPath}")]
public sealed class AlternateDataStreamInfo : IEquatable<AlternateDataStreamInfo>
{
#region Private Data
private readonly string _fullPath;
private readonly string _filePath;
private readonly string _streamName;
private readonly FileStreamType _streamType;
private readonly FileStreamAttributes _attributes;
private readonly long _size;
private readonly bool _exists;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="AlternateDataStreamInfo"/> class.
/// </summary>
/// <param name="filePath">
/// The full path of the file.
/// This argument must not be <see langword="null"/>.
/// </param>
/// <param name="info">
/// The <see cref="SafeNativeMethods.Win32StreamInfo"/> containing the stream information.
/// </param>
internal AlternateDataStreamInfo(string filePath, SafeNativeMethods.Win32StreamInfo info)
{
_filePath = filePath;
_streamName = info.StreamName;
_streamType = info.StreamType;
_attributes = info.StreamAttributes;
_size = info.StreamSize;
_exists = true;
_fullPath = SafeNativeMethods.BuildStreamPath(_filePath, _streamName);
}
/// <summary>
/// Initializes a new instance of the <see cref="AlternateDataStreamInfo"/> class.
/// </summary>
/// <param name="filePath">
/// The full path of the file.
/// This argument must not be <see langword="null"/>.
/// </param>
/// <param name="streamName">
/// The name of the stream
/// This argument must not be <see langword="null"/>.
/// </param>
/// <param name="fullPath">
/// The full path of the stream.
/// If this argument is <see langword="null"/>, it will be generated from the
/// <paramref name="filePath"/> and <paramref name="streamName"/> arguments.
/// </param>
/// <param name="exists">
/// <see langword="true"/> if the stream exists;
/// otherwise, <see langword="false"/>.
/// </param>
internal AlternateDataStreamInfo(string filePath, string streamName, string fullPath, bool exists)
{
if (string.IsNullOrEmpty(fullPath)) fullPath = SafeNativeMethods.BuildStreamPath(filePath, streamName);
_streamType = FileStreamType.AlternateDataStream;
_filePath = filePath;
_streamName = streamName;
_fullPath = fullPath;
_exists = exists;
if (_exists)
{
_size = SafeNativeMethods.GetFileSize(_fullPath);
}
}
#endregion
#region Properties
/// <summary>
/// Returns the full path of this stream.
/// </summary>
/// <value>
/// The full path of this stream.
/// </value>
public string FullPath
{
get { return _fullPath; }
}
/// <summary>
/// Returns the full path of the file which contains the stream.
/// </summary>
/// <value>
/// The full file-system path of the file which contains the stream.
/// </value>
public string FilePath
{
get { return _filePath; }
}
/// <summary>
/// Returns the name of the stream.
/// </summary>
/// <value>
/// The name of the stream.
/// </value>
public string Name
{
get { return _streamName; }
}
/// <summary>
/// Returns a flag indicating whether the specified stream exists.
/// </summary>
/// <value>
/// <see langword="true"/> if the stream exists;
/// otherwise, <see langword="false"/>.
/// </value>
public bool Exists
{
get { return _exists; }
}
/// <summary>
/// Returns the size of the stream, in bytes.
/// </summary>
/// <value>
/// The size of the stream, in bytes.
/// </value>
public long Size
{
get { return _size; }
}
/// <summary>
/// Returns the type of data.
/// </summary>
/// <value>
/// One of the <see cref="FileStreamType"/> values.
/// </value>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public FileStreamType StreamType
{
get { return _streamType; }
}
/// <summary>
/// Returns attributes of the data stream.
/// </summary>
/// <value>
/// A combination of <see cref="FileStreamAttributes"/> values.
/// </value>
[EditorBrowsable(EditorBrowsableState.Advanced)]
public FileStreamAttributes Attributes
{
get { return _attributes; }
}
#endregion
#region Methods
#region -IEquatable
/// <summary>
/// Returns a <see cref="String"/> that represents the current instance.
/// </summary>
/// <returns>
/// A <see cref="String"/> that represents the current instance.
/// </returns>
public override string ToString()
{
return this.FullPath;
}
/// <summary>
/// Serves as a hash function for a particular type.
/// </summary>
/// <returns>
/// A hash code for the current <see cref="Object"/>.
/// </returns>
public override int GetHashCode()
{
var comparer = StringComparer.OrdinalIgnoreCase;
return comparer.GetHashCode(_filePath ?? string.Empty)
^ comparer.GetHashCode(_streamName ?? string.Empty);
}
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <param name="obj">
/// An object to compare with this object.
/// </param>
/// <returns>
/// <see langword="true"/> if the current object is equal to the <paramref name="obj"/> parameter;
/// otherwise, <see langword="false"/>.
/// </returns>
public override bool Equals(object obj)
{
if (object.ReferenceEquals(null, obj)) return false;
if (object.ReferenceEquals(this, obj)) return true;
AlternateDataStreamInfo other = obj as AlternateDataStreamInfo;
if (!object.ReferenceEquals(null, other)) return this.Equals(other);
return false;
}
/// <summary>
/// Returns a value indicating whether
/// this instance is equal to another instance.
/// </summary>
/// <param name="other">
/// The instance to compare to.
/// </param>
/// <returns>
/// <see langword="true"/> if the current object is equal to the <paramref name="other"/> parameter;
/// otherwise, <see langword="false"/>.
/// </returns>
public bool Equals(AlternateDataStreamInfo other)
{
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;
var comparer = StringComparer.OrdinalIgnoreCase;
return comparer.Equals(this._filePath ?? string.Empty, other._filePath ?? string.Empty)
&& comparer.Equals(this._streamName ?? string.Empty, other._streamName ?? string.Empty);
}
/// <summary>
/// The equality operator.
/// </summary>
/// <param name="first">
/// The first object.
/// </param>
/// <param name="second">
/// The second object.
/// </param>
/// <returns>
/// <see langword="true"/> if the two objects are equal;
/// otherwise, <see langword="false"/>.
/// </returns>
public static bool operator ==(AlternateDataStreamInfo first, AlternateDataStreamInfo second)
{
if (object.ReferenceEquals(first, second)) return true;
if (object.ReferenceEquals(null, first)) return false;
if (object.ReferenceEquals(null, second)) return false;
return first.Equals(second);
}
/// <summary>
/// The inequality operator.
/// </summary>
/// <param name="first">
/// The first object.
/// </param>
/// <param name="second">
/// The second object.
/// </param>
/// <returns>
/// <see langword="true"/> if the two objects are not equal;
/// otherwise, <see langword="false"/>.
/// </returns>
public static bool operator !=(AlternateDataStreamInfo first, AlternateDataStreamInfo second)
{
if (object.ReferenceEquals(first, second)) return false;
if (object.ReferenceEquals(null, first)) return true;
if (object.ReferenceEquals(null, second)) return true;
return !first.Equals(second);
}
#endregion
#region -Delete
/// <summary>
/// Deletes this stream from the parent file.
/// </summary>
/// <returns>
/// <see langword="true"/> if the stream was deleted;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
public bool Delete()
{
const FileIOPermissionAccess permAccess = FileIOPermissionAccess.Write;
new FileIOPermission(permAccess, _filePath).Demand();
return SafeNativeMethods.SafeDeleteFile(this.FullPath);
}
#endregion
#region -Open
/// <summary>
/// Calculates the access to demand.
/// </summary>
/// <param name="mode">
/// The <see cref="FileMode"/>.
/// </param>
/// <param name="access">
/// The <see cref="FileAccess"/>.
/// </param>
/// <returns>
/// The <see cref="FileIOPermissionAccess"/>.
/// </returns>
private static FileIOPermissionAccess CalculateAccess(FileMode mode, FileAccess access)
{
FileIOPermissionAccess permAccess = FileIOPermissionAccess.NoAccess;
switch (mode)
{
case FileMode.Append:
permAccess = FileIOPermissionAccess.Append;
break;
case FileMode.Create:
case FileMode.CreateNew:
case FileMode.OpenOrCreate:
case FileMode.Truncate:
permAccess = FileIOPermissionAccess.Write;
break;
case FileMode.Open:
permAccess = FileIOPermissionAccess.Read;
break;
}
switch (access)
{
case FileAccess.ReadWrite:
permAccess |= FileIOPermissionAccess.Write;
permAccess |= FileIOPermissionAccess.Read;
break;
case FileAccess.Write:
permAccess |= FileIOPermissionAccess.Write;
break;
case FileAccess.Read:
permAccess |= FileIOPermissionAccess.Read;
break;
}
return permAccess;
}
/// <summary>
/// Opens this alternate data stream.
/// </summary>
/// <param name="mode">
/// A <see cref="FileMode"/> value that specifies whether a stream is created if one does not exist,
/// and determines whether the contents of existing streams are retained or overwritten.
/// </param>
/// <param name="access">
/// A <see cref="FileAccess"/> value that specifies the operations that can be performed on the stream.
/// </param>
/// <param name="share">
/// A <see cref="FileShare"/> value specifying the type of access other threads have to the file.
/// </param>
/// <param name="bufferSize">
/// The size of the buffer to use.
/// </param>
/// <param name="useAsync">
/// <see langword="true"/> to enable async-IO;
/// otherwise, <see langword="false"/>.
/// </param>
/// <returns>
/// A <see cref="FileStream"/> for this alternate data stream.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="bufferSize"/> is less than or equal to zero.
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream Open(FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
{
if (0 >= bufferSize) throw new ArgumentOutOfRangeException("bufferSize", bufferSize, null);
FileIOPermissionAccess permAccess = CalculateAccess(mode, access);
new FileIOPermission(permAccess, _filePath).Demand();
SafeNativeMethods.NativeFileFlags flags = useAsync ? SafeNativeMethods.NativeFileFlags.Overlapped : 0;
var handle = SafeNativeMethods.SafeCreateFile(this.FullPath, access.ToNative(), share, IntPtr.Zero, mode, flags, IntPtr.Zero);
if (handle.IsInvalid) SafeNativeMethods.ThrowLastIOError(this.FullPath);
return new FileStream(handle, access, bufferSize, useAsync);
}
/// <summary>
/// Opens this alternate data stream.
/// </summary>
/// <param name="mode">
/// A <see cref="FileMode"/> value that specifies whether a stream is created if one does not exist,
/// and determines whether the contents of existing streams are retained or overwritten.
/// </param>
/// <param name="access">
/// A <see cref="FileAccess"/> value that specifies the operations that can be performed on the stream.
/// </param>
/// <param name="share">
/// A <see cref="FileShare"/> value specifying the type of access other threads have to the file.
/// </param>
/// <param name="bufferSize">
/// The size of the buffer to use.
/// </param>
/// <returns>
/// A <see cref="FileStream"/> for this alternate data stream.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="bufferSize"/> is less than or equal to zero.
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream Open(FileMode mode, FileAccess access, FileShare share, int bufferSize)
{
return this.Open(mode, access, share, bufferSize, false);
}
/// <summary>
/// Opens this alternate data stream.
/// </summary>
/// <param name="mode">
/// A <see cref="FileMode"/> value that specifies whether a stream is created if one does not exist,
/// and determines whether the contents of existing streams are retained or overwritten.
/// </param>
/// <param name="access">
/// A <see cref="FileAccess"/> value that specifies the operations that can be performed on the stream.
/// </param>
/// <param name="share">
/// A <see cref="FileShare"/> value specifying the type of access other threads have to the file.
/// </param>
/// <returns>
/// A <see cref="FileStream"/> for this alternate data stream.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream Open(FileMode mode, FileAccess access, FileShare share)
{
return this.Open(mode, access, share, SafeNativeMethods.DefaultBufferSize, false);
}
/// <summary>
/// Opens this alternate data stream.
/// </summary>
/// <param name="mode">
/// A <see cref="FileMode"/> value that specifies whether a stream is created if one does not exist,
/// and determines whether the contents of existing streams are retained or overwritten.
/// </param>
/// <param name="access">
/// A <see cref="FileAccess"/> value that specifies the operations that can be performed on the stream.
/// </param>
/// <returns>
/// A <see cref="FileStream"/> for this alternate data stream.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream Open(FileMode mode, FileAccess access)
{
return this.Open(mode, access, FileShare.None, SafeNativeMethods.DefaultBufferSize, false);
}
/// <summary>
/// Opens this alternate data stream.
/// </summary>
/// <param name="mode">
/// A <see cref="FileMode"/> value that specifies whether a stream is created if one does not exist,
/// and determines whether the contents of existing streams are retained or overwritten.
/// </param>
/// <returns>
/// A <see cref="FileStream"/> for this alternate data stream.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream Open(FileMode mode)
{
FileAccess access = (FileMode.Append == mode) ? FileAccess.Write : FileAccess.ReadWrite;
return this.Open(mode, access, FileShare.None, SafeNativeMethods.DefaultBufferSize, false);
}
#endregion
#region -OpenRead / OpenWrite / OpenText
/// <summary>
/// Opens this stream for reading.
/// </summary>
/// <returns>
/// A read-only <see cref="FileStream"/> for this stream.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream OpenRead()
{
return this.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
}
/// <summary>
/// Opens this stream for writing.
/// </summary>
/// <returns>
/// A write-only <see cref="FileStream"/> for this stream.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public FileStream OpenWrite()
{
return this.Open(FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
}
/// <summary>
/// Opens this stream as a text file.
/// </summary>
/// <returns>
/// A <see cref="StreamReader"/> which can be used to read the contents of this stream.
/// </returns>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
/// <exception cref="ArgumentException">
/// The path of the stream is invalid.
/// </exception>
/// <exception cref="Win32Exception">
/// There was an error opening the stream.
/// </exception>
public StreamReader OpenText()
{
Stream fileStream = this.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
return new StreamReader(fileStream);
}
#endregion
#endregion
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace Trinet.Core.IO.Ntfs
{
/// <summary>
/// Represents the attributes of a file stream.
/// </summary>
[Flags]
public enum FileStreamAttributes
{
/// <summary>
/// No attributes.
/// </summary>
None = 0,
/// <summary>
/// Set if the stream contains data that is modified when read.
/// </summary>
ModifiedWhenRead = 1,
/// <summary>
/// Set if the stream contains security data.
/// </summary>
ContainsSecurity = 2,
/// <summary>
/// Set if the stream contains properties.
/// </summary>
ContainsProperties = 4,
/// <summary>
/// Set if the stream is sparse.
/// </summary>
Sparse = 8,
}
}

View File

@@ -0,0 +1,56 @@
using System;
namespace Trinet.Core.IO.Ntfs
{
/// <summary>
/// Represents the type of data in a stream.
/// </summary>
public enum FileStreamType
{
/// <summary>
/// Unknown stream type.
/// </summary>
Unknown = 0,
/// <summary>
/// Standard data.
/// </summary>
Data = 1,
/// <summary>
/// Extended attribute data.
/// </summary>
ExtendedAttributes = 2,
/// <summary>
/// Security data.
/// </summary>
SecurityData = 3,
/// <summary>
/// Alternate data stream.
/// </summary>
AlternateDataStream = 4,
/// <summary>
/// Hard link information.
/// </summary>
Link = 5,
/// <summary>
/// Property data.
/// </summary>
PropertyData = 6,
/// <summary>
/// Object identifiers.
/// </summary>
ObjectId = 7,
/// <summary>
/// Reparse points.
/// </summary>
ReparseData = 8,
/// <summary>
/// Sparse file.
/// </summary>
SparseBlock = 9,
/// <summary>
/// Transactional data.
/// (Undocumented - BACKUP_TXFS_DATA)
/// </summary>
TransactionData = 10,
}
}

View File

@@ -0,0 +1,452 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;
using System.Security.Permissions;
namespace Trinet.Core.IO.Ntfs
{
using Resources = Properties.Resources;
/// <summary>
/// File-system utilities.
/// </summary>
public static class FileSystem
{
#region Create FileSystemInfo
/// <summary>
/// Creates a <see cref="FileSystemInfo"/> for the specified path.
/// </summary>
/// <param name="path">
/// The path of the file or directory.
/// </param>
/// <returns>
/// The <see cref="FileSystemInfo"/> representing the file or directory.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="path"/> is <see langword="null"/> or empty.
/// </exception>
private static FileSystemInfo CreateInfo(string path)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
path = Path.GetFullPath(path);
if (!File.Exists(path) && Directory.Exists(path)) return new DirectoryInfo(path);
return new FileInfo(path);
}
#endregion
#region List Streams
/// <summary>
/// <span style="font-weight:bold;color:#a00;">(Extension Method)</span><br />
/// Returns a read-only list of alternate data streams for the specified file.
/// </summary>
/// <param name="file">
/// The <see cref="FileSystemInfo"/> to inspect.
/// </param>
/// <returns>
/// A read-only list of <see cref="AlternateDataStreamInfo"/> objects
/// representing the alternate data streams for the specified file, if any.
/// If no streams are found, returns an empty list.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="file"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The specified <paramref name="file"/> does not exist.
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission.
/// </exception>
public static IList<AlternateDataStreamInfo> ListAlternateDataStreams(this FileSystemInfo file)
{
if (null == file) throw new ArgumentNullException("file");
if (!file.Exists) throw new FileNotFoundException(null, file.FullName);
string path = file.FullName;
new FileIOPermission(FileIOPermissionAccess.Read, path).Demand();
return SafeNativeMethods.ListStreams(path)
.Select(s => new AlternateDataStreamInfo(path, s))
.ToList().AsReadOnly();
}
/// <summary>
/// Returns a read-only list of alternate data streams for the specified file.
/// </summary>
/// <param name="filePath">
/// The full path of the file to inspect.
/// </param>
/// <returns>
/// A read-only list of <see cref="AlternateDataStreamInfo"/> objects
/// representing the alternate data streams for the specified file, if any.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="filePath"/> is <see langword="null"/> or an empty string.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="filePath"/> is not a valid file path.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The specified <paramref name="filePath"/> does not exist.
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission.
/// </exception>
public static IList<AlternateDataStreamInfo> ListAlternateDataStreams(string filePath)
{
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");
return CreateInfo(filePath).ListAlternateDataStreams();
}
#endregion
#region Stream Exists
/// <summary>
/// <span style="font-weight:bold;color:#a00;">(Extension Method)</span><br />
/// Returns a flag indicating whether the specified alternate data stream exists.
/// </summary>
/// <param name="file">
/// The <see cref="FileInfo"/> to inspect.
/// </param>
/// <param name="streamName">
/// The name of the stream to find.
/// </param>
/// <returns>
/// <see langword="true"/> if the specified stream exists;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="file"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="streamName"/> contains invalid characters.
/// </exception>
public static bool AlternateDataStreamExists(this FileSystemInfo file, string streamName)
{
if (null == file) throw new ArgumentNullException("file");
SafeNativeMethods.ValidateStreamName(streamName);
string path = SafeNativeMethods.BuildStreamPath(file.FullName, streamName);
return -1 != SafeNativeMethods.SafeGetFileAttributes(path);
}
/// <summary>
/// Returns a flag indicating whether the specified alternate data stream exists.
/// </summary>
/// <param name="filePath">
/// The path of the file to inspect.
/// </param>
/// <param name="streamName">
/// The name of the stream to find.
/// </param>
/// <returns>
/// <see langword="true"/> if the specified stream exists;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="filePath"/> is <see langword="null"/> or an empty string.
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="filePath"/> is not a valid file path.</para>
/// <para>-or-</para>
/// <para><paramref name="streamName"/> contains invalid characters.</para>
/// </exception>
public static bool AlternateDataStreamExists(string filePath, string streamName)
{
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");
return CreateInfo(filePath).AlternateDataStreamExists(streamName);
}
#endregion
#region Open Stream
/// <summary>
/// <span style="font-weight:bold;color:#a00;">(Extension Method)</span><br />
/// Opens an alternate data stream.
/// </summary>
/// <param name="file">
/// The <see cref="FileInfo"/> which contains the stream.
/// </param>
/// <param name="streamName">
/// The name of the stream to open.
/// </param>
/// <param name="mode">
/// One of the <see cref="FileMode"/> values, indicating how the stream is to be opened.
/// </param>
/// <returns>
/// An <see cref="AlternateDataStreamInfo"/> representing the stream.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="file"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The specified <paramref name="file"/> was not found.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="streamName"/> contains invalid characters.
/// </exception>
/// <exception cref="NotSupportedException">
/// <paramref name="mode"/> is either <see cref="FileMode.Truncate"/> or <see cref="FileMode.Append"/>.
/// </exception>
/// <exception cref="IOException">
/// <para><paramref name="mode"/> is <see cref="FileMode.Open"/>, and the stream doesn't exist.</para>
/// <para>-or-</para>
/// <para><paramref name="mode"/> is <see cref="FileMode.CreateNew"/>, and the stream already exists.</para>
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
public static AlternateDataStreamInfo GetAlternateDataStream(this FileSystemInfo file, string streamName, FileMode mode)
{
if (null == file) throw new ArgumentNullException("file");
if (!file.Exists) throw new FileNotFoundException(null, file.FullName);
SafeNativeMethods.ValidateStreamName(streamName);
if (FileMode.Truncate == mode || FileMode.Append == mode)
{
throw new NotSupportedException(string.Format(Resources.Culture,
Resources.Error_InvalidMode, mode));
}
FileIOPermissionAccess permAccess = (FileMode.Open == mode) ? FileIOPermissionAccess.Read : FileIOPermissionAccess.Read | FileIOPermissionAccess.Write;
new FileIOPermission(permAccess, file.FullName).Demand();
string path = SafeNativeMethods.BuildStreamPath(file.FullName, streamName);
bool exists = -1 != SafeNativeMethods.SafeGetFileAttributes(path);
if (!exists && FileMode.Open == mode)
{
throw new IOException(string.Format(Resources.Culture,
Resources.Error_StreamNotFound, streamName, file.Name));
}
if (exists && FileMode.CreateNew == mode)
{
throw new IOException(string.Format(Resources.Culture,
Resources.Error_StreamExists, streamName, file.Name));
}
return new AlternateDataStreamInfo(file.FullName, streamName, path, exists);
}
/// <summary>
/// <span style="font-weight:bold;color:#a00;">(Extension Method)</span><br />
/// Opens an alternate data stream.
/// </summary>
/// <param name="file">
/// The <see cref="FileInfo"/> which contains the stream.
/// </param>
/// <param name="streamName">
/// The name of the stream to open.
/// </param>
/// <returns>
/// An <see cref="AlternateDataStreamInfo"/> representing the stream.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="file"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The specified <paramref name="file"/> was not found.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="streamName"/> contains invalid characters.
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
public static AlternateDataStreamInfo GetAlternateDataStream(this FileSystemInfo file, string streamName)
{
return file.GetAlternateDataStream(streamName, FileMode.OpenOrCreate);
}
/// <summary>
/// Opens an alternate data stream.
/// </summary>
/// <param name="filePath">
/// The path of the file which contains the stream.
/// </param>
/// <param name="streamName">
/// The name of the stream to open.
/// </param>
/// <param name="mode">
/// One of the <see cref="FileMode"/> values, indicating how the stream is to be opened.
/// </param>
/// <returns>
/// An <see cref="AlternateDataStreamInfo"/> representing the stream.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="filePath"/> is <see langword="null"/> or an empty string.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The specified <paramref name="filePath"/> was not found.
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="filePath"/> is not a valid file path.</para>
/// <para>-or-</para>
/// <para><paramref name="streamName"/> contains invalid characters.</para>
/// </exception>
/// <exception cref="NotSupportedException">
/// <paramref name="mode"/> is either <see cref="FileMode.Truncate"/> or <see cref="FileMode.Append"/>.
/// </exception>
/// <exception cref="IOException">
/// <para><paramref name="mode"/> is <see cref="FileMode.Open"/>, and the stream doesn't exist.</para>
/// <para>-or-</para>
/// <para><paramref name="mode"/> is <see cref="FileMode.CreateNew"/>, and the stream already exists.</para>
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
public static AlternateDataStreamInfo GetAlternateDataStream(string filePath, string streamName, FileMode mode)
{
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");
return CreateInfo(filePath).GetAlternateDataStream(streamName, mode);
}
/// <summary>
/// Opens an alternate data stream.
/// </summary>
/// <param name="filePath">
/// The path of the file which contains the stream.
/// </param>
/// <param name="streamName">
/// The name of the stream to open.
/// </param>
/// <returns>
/// An <see cref="AlternateDataStreamInfo"/> representing the stream.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="filePath"/> is <see langword="null"/> or an empty string.
/// </exception>
/// <exception cref="FileNotFoundException">
/// The specified <paramref name="filePath"/> was not found.
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="filePath"/> is not a valid file path.</para>
/// <para>-or-</para>
/// <para><paramref name="streamName"/> contains invalid characters.</para>
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
public static AlternateDataStreamInfo GetAlternateDataStream(string filePath, string streamName)
{
return GetAlternateDataStream(filePath, streamName, FileMode.OpenOrCreate);
}
#endregion
#region Delete Stream
/// <summary>
/// <span style="font-weight:bold;color:#a00;">(Extension Method)</span><br />
/// Deletes the specified alternate data stream if it exists.
/// </summary>
/// <param name="file">
/// The <see cref="FileInfo"/> to inspect.
/// </param>
/// <param name="streamName">
/// The name of the stream to delete.
/// </param>
/// <returns>
/// <see langword="true"/> if the specified stream is deleted;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="file"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="streamName"/> contains invalid characters.
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
public static bool DeleteAlternateDataStream(this FileSystemInfo file, string streamName)
{
if (null == file) throw new ArgumentNullException("file");
SafeNativeMethods.ValidateStreamName(streamName);
const FileIOPermissionAccess permAccess = FileIOPermissionAccess.Write;
new FileIOPermission(permAccess, file.FullName).Demand();
var result = false;
if (file.Exists)
{
string path = SafeNativeMethods.BuildStreamPath(file.FullName, streamName);
if (-1 != SafeNativeMethods.SafeGetFileAttributes(path))
{
result = SafeNativeMethods.SafeDeleteFile(path);
}
}
return result;
}
/// <summary>
/// Deletes the specified alternate data stream if it exists.
/// </summary>
/// <param name="filePath">
/// The path of the file to inspect.
/// </param>
/// <param name="streamName">
/// The name of the stream to find.
/// </param>
/// <returns>
/// <see langword="true"/> if the specified stream is deleted;
/// otherwise, <see langword="false"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="filePath"/> is <see langword="null"/> or an empty string.
/// </exception>
/// <exception cref="ArgumentException">
/// <para><paramref name="filePath"/> is not a valid file path.</para>
/// <para>-or-</para>
/// <para><paramref name="streamName"/> contains invalid characters.</para>
/// </exception>
/// <exception cref="SecurityException">
/// The caller does not have the required permission.
/// </exception>
/// <exception cref="UnauthorizedAccessException">
/// The caller does not have the required permission, or the file is read-only.
/// </exception>
/// <exception cref="IOException">
/// The specified file is in use.
/// </exception>
public static bool DeleteAlternateDataStream(string filePath, string streamName)
{
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");
return CreateInfo(filePath).DeleteAlternateDataStream(streamName);
}
#endregion
}
}

View File

@@ -0,0 +1,118 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
namespace Trinet.Core.IO.Ntfs
{
/// <summary>
/// A <see cref="SafeHandle"/> for a global memory allocation.
/// </summary>
internal sealed class SafeHGlobalHandle : SafeHandle
{
#region Private Data
private readonly int _size;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="SafeHGlobalHandle"/> class.
/// </summary>
/// <param name="toManage">
/// The initial handle value.
/// </param>
/// <param name="size">
/// The size of this memory block, in bytes.
/// </param>
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private SafeHGlobalHandle(IntPtr toManage, int size) : base(IntPtr.Zero, true)
{
_size = size;
base.SetHandle(toManage);
}
/// <summary>
/// Initializes a new instance of the <see cref="SafeHGlobalHandle"/> class.
/// </summary>
private SafeHGlobalHandle() : base(IntPtr.Zero, true)
{
}
#endregion
#region Properties
/// <summary>
/// Gets a value indicating whether the handle value is invalid.
/// </summary>
/// <value>
/// <see langword="true"/> if the handle value is invalid;
/// otherwise, <see langword="false"/>.
/// </value>
public override bool IsInvalid
{
get { return IntPtr.Zero == base.handle; }
}
/// <summary>
/// Returns the size of this memory block.
/// </summary>
/// <value>
/// The size of this memory block, in bytes.
/// </value>
public int Size
{
get { return _size; }
}
#endregion
#region Methods
/// <summary>
/// Allocates memory from the unmanaged memory of the process using GlobalAlloc.
/// </summary>
/// <param name="bytes">
/// The number of bytes in memory required.
/// </param>
/// <returns>
/// A <see cref="SafeHGlobalHandle"/> representing the memory.
/// </returns>
/// <exception cref="OutOfMemoryException">
/// There is insufficient memory to satisfy the request.
/// </exception>
public static SafeHGlobalHandle Allocate(int bytes)
{
return new SafeHGlobalHandle(Marshal.AllocHGlobal(bytes), bytes);
}
/// <summary>
/// Returns an invalid handle.
/// </summary>
/// <returns>
/// An invalid <see cref="SafeHGlobalHandle"/>.
/// </returns>
public static SafeHGlobalHandle Invalid()
{
return new SafeHGlobalHandle();
}
/// <summary>
/// Executes the code required to free the handle.
/// </summary>
/// <returns>
/// <see langword="true"/> if the handle is released successfully;
/// otherwise, in the event of a catastrophic failure, <see langword="false"/>.
/// In this case, it generates a releaseHandleFailed MDA Managed Debugging Assistant.
/// </returns>
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(base.handle);
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,478 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace Trinet.Core.IO.Ntfs
{
using Resources = Properties.Resources;
/// <summary>
/// Safe native methods.
/// </summary>
internal static class SafeNativeMethods
{
#region Constants and flags
public const int MaxPath = 256;
private const string LongPathPrefix = @"\\?\";
public const char StreamSeparator = ':';
public const int DefaultBufferSize = 0x1000;
private const int ErrorFileNotFound = 2;
// "Characters whose integer representations are in the range from 1 through 31,
// except for alternate streams where these characters are allowed"
// http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx
private static readonly char[] InvalidStreamNameChars = Path.GetInvalidFileNameChars().Where(c => c < 1 || c > 31).ToArray();
[Flags]
public enum NativeFileFlags : uint
{
WriteThrough = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x8000000,
DeleteOnClose = 0x4000000,
BackupSemantics = 0x2000000,
PosixSemantics = 0x1000000,
OpenReparsePoint = 0x200000,
OpenNoRecall = 0x100000
}
[Flags]
public enum NativeFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000
}
#endregion
#region P/Invoke Structures
[StructLayout(LayoutKind.Sequential)]
private struct LargeInteger
{
public readonly int Low;
public readonly int High;
public long ToInt64()
{
return (this.High * 0x100000000) + this.Low;
}
/*
public static LargeInteger FromInt64(long value)
{
return new LargeInteger
{
Low = (int)(value & 0x11111111),
High = (int)((value / 0x100000000) & 0x11111111)
};
}
*/
}
[StructLayout(LayoutKind.Sequential)]
private struct Win32StreamId
{
public readonly int StreamId;
public readonly int StreamAttributes;
public LargeInteger Size;
public readonly int StreamNameSize;
}
/*
[StructLayout(LayoutKind.Sequential)]
private struct FileInformationByHandle
{
public int dwFileAttributes;
public LargeInteger ftCreationTime;
public LargeInteger ftLastAccessTime;
public LargeInteger ftLastWriteTime;
public int dwVolumeSerialNumber;
public LargeInteger FileSize;
public int nNumberOfLinks;
public LargeInteger FileIndex;
}
*/
#endregion
#region P/Invoke Methods
[DllImport("kernel32.dll", CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)]
private static extern int FormatMessage(
int dwFlags,
IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
StringBuilder lpBuffer,
int nSize,
IntPtr vaListArguments);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int GetFileAttributes(string fileName);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetFileSizeEx(SafeFileHandle handle, out LargeInteger size);
[DllImport("kernel32.dll")]
private static extern int GetFileType(SafeFileHandle handle);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern SafeFileHandle CreateFile(
string name,
NativeFileAccess access,
FileShare share,
IntPtr security,
FileMode mode,
NativeFileFlags flags,
IntPtr template);
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteFile(string name);
[DllImport("kernel32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BackupRead(
SafeFileHandle hFile,
ref Win32StreamId pBuffer,
int numberOfBytesToRead,
out int numberOfBytesRead,
[MarshalAs(UnmanagedType.Bool)] bool abort,
[MarshalAs(UnmanagedType.Bool)] bool processSecurity,
ref IntPtr context);
[DllImport("kernel32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BackupRead(
SafeFileHandle hFile,
SafeHGlobalHandle pBuffer,
int numberOfBytesToRead,
out int numberOfBytesRead,
[MarshalAs(UnmanagedType.Bool)] bool abort,
[MarshalAs(UnmanagedType.Bool)] bool processSecurity,
ref IntPtr context);
[DllImport("kernel32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BackupSeek(
SafeFileHandle hFile,
int bytesToSeekLow,
int bytesToSeekHigh,
out int bytesSeekedLow,
out int bytesSeekedHigh,
ref IntPtr context);
#endregion
#region Utility Structures
public struct Win32StreamInfo
{
public FileStreamType StreamType;
public FileStreamAttributes StreamAttributes;
public long StreamSize;
public string StreamName;
}
#endregion
#region Utility Methods
private static int MakeHRFromErrorCode(int errorCode)
{
return (-2147024896 | errorCode);
}
private static string GetErrorMessage(int errorCode)
{
var lpBuffer = new StringBuilder(0x200);
if (0 != FormatMessage(0x3200, IntPtr.Zero, errorCode, 0, lpBuffer, lpBuffer.Capacity, IntPtr.Zero))
{
return lpBuffer.ToString();
}
return string.Format(Resources.Culture, Resources.Error_UnknownError, errorCode);
}
private static void ThrowIOError(int errorCode, string path)
{
switch (errorCode)
{
case 0:
{
break;
}
case 2: // File not found
{
if (string.IsNullOrEmpty(path)) throw new FileNotFoundException();
throw new FileNotFoundException(null, path);
}
case 3: // Directory not found
{
if (string.IsNullOrEmpty(path)) throw new DirectoryNotFoundException();
throw new DirectoryNotFoundException(string.Format(Resources.Culture, Resources.Error_DirectoryNotFound, path));
}
case 5: // Access denied
{
if (string.IsNullOrEmpty(path)) throw new UnauthorizedAccessException();
throw new UnauthorizedAccessException(string.Format(Resources.Culture, Resources.Error_AccessDenied_Path, path));
}
case 15: // Drive not found
{
if (string.IsNullOrEmpty(path)) throw new DriveNotFoundException();
throw new DriveNotFoundException(string.Format(Resources.Culture, Resources.Error_DriveNotFound, path));
}
case 32: // Sharing violation
{
if (string.IsNullOrEmpty(path)) throw new IOException(GetErrorMessage(errorCode), MakeHRFromErrorCode(errorCode));
throw new IOException(string.Format(Resources.Culture, Resources.Error_SharingViolation, path), MakeHRFromErrorCode(errorCode));
}
case 80: // File already exists
{
if (!string.IsNullOrEmpty(path))
{
throw new IOException(string.Format(Resources.Culture, Resources.Error_FileAlreadyExists, path), MakeHRFromErrorCode(errorCode));
}
break;
}
case 87: // Invalid parameter
{
throw new IOException(GetErrorMessage(errorCode), MakeHRFromErrorCode(errorCode));
}
case 183: // File or directory already exists
{
if (!string.IsNullOrEmpty(path))
{
throw new IOException(string.Format(Resources.Culture, Resources.Error_AlreadyExists, path), MakeHRFromErrorCode(errorCode));
}
break;
}
case 206: // Path too long
{
throw new PathTooLongException();
}
case 995: // Operation cancelled
{
throw new OperationCanceledException();
}
default:
{
Marshal.ThrowExceptionForHR(MakeHRFromErrorCode(errorCode));
break;
}
}
}
public static void ThrowLastIOError(string path)
{
int errorCode = Marshal.GetLastWin32Error();
if (0 != errorCode)
{
int hr = Marshal.GetHRForLastWin32Error();
if (0 <= hr) throw new Win32Exception(errorCode);
ThrowIOError(errorCode, path);
}
}
public static NativeFileAccess ToNative(this FileAccess access)
{
NativeFileAccess result = 0;
if (FileAccess.Read == (FileAccess.Read & access)) result |= NativeFileAccess.GenericRead;
if (FileAccess.Write == (FileAccess.Write & access)) result |= NativeFileAccess.GenericWrite;
return result;
}
public static string BuildStreamPath(string filePath, string streamName)
{
string result = filePath;
if (!string.IsNullOrEmpty(filePath))
{
if (1 == result.Length) result = ".\\" + result;
result += StreamSeparator + streamName + StreamSeparator + "$DATA";
if (MaxPath <= result.Length) result = LongPathPrefix + result;
}
return result;
}
public static void ValidateStreamName(string streamName)
{
if (!string.IsNullOrEmpty(streamName) && -1 != streamName.IndexOfAny(InvalidStreamNameChars))
{
throw new ArgumentException(Resources.Error_InvalidFileChars);
}
}
public static int SafeGetFileAttributes(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
int result = GetFileAttributes(name);
if (-1 == result)
{
int errorCode = Marshal.GetLastWin32Error();
if (ErrorFileNotFound != errorCode) ThrowLastIOError(name);
}
return result;
}
public static bool SafeDeleteFile(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
bool result = DeleteFile(name);
if (!result)
{
int errorCode = Marshal.GetLastWin32Error();
if (ErrorFileNotFound != errorCode) ThrowLastIOError(name);
}
return result;
}
public static SafeFileHandle SafeCreateFile(string path, NativeFileAccess access, FileShare share, IntPtr security, FileMode mode, NativeFileFlags flags, IntPtr template)
{
SafeFileHandle result = CreateFile(path, access, share, security, mode, flags, template);
if (!result.IsInvalid && 1 != GetFileType(result))
{
result.Dispose();
throw new NotSupportedException(string.Format(Resources.Culture,
Resources.Error_NonFile, path));
}
return result;
}
private static long GetFileSize(string path, SafeFileHandle handle)
{
long result = 0L;
if (null != handle && !handle.IsInvalid)
{
LargeInteger value;
if (GetFileSizeEx(handle, out value))
{
result = value.ToInt64();
}
else
{
ThrowLastIOError(path);
}
}
return result;
}
public static long GetFileSize(string path)
{
long result = 0L;
if (!string.IsNullOrEmpty(path))
{
using (SafeFileHandle handle = SafeCreateFile(path, NativeFileAccess.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero))
{
result = GetFileSize(path, handle);
}
}
return result;
}
public static IList<Win32StreamInfo> ListStreams(string filePath)
{
if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException("filePath");
if (-1 != filePath.IndexOfAny(Path.GetInvalidPathChars())) throw new ArgumentException(Resources.Error_InvalidFileChars, "filePath");
var result = new List<Win32StreamInfo>();
using (SafeFileHandle hFile = SafeCreateFile(filePath, NativeFileAccess.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, NativeFileFlags.BackupSemantics, IntPtr.Zero))
using (var hName = new StreamName())
{
if (!hFile.IsInvalid)
{
var streamId = new Win32StreamId();
int dwStreamHeaderSize = Marshal.SizeOf(streamId);
bool finished = false;
IntPtr context = IntPtr.Zero;
int bytesRead;
string name;
try
{
while (!finished)
{
// Read the next stream header:
if (!BackupRead(hFile, ref streamId, dwStreamHeaderSize, out bytesRead, false, false, ref context))
{
finished = true;
}
else if (dwStreamHeaderSize != bytesRead)
{
finished = true;
}
else
{
// Read the stream name:
if (0 >= streamId.StreamNameSize)
{
name = null;
}
else
{
hName.EnsureCapacity(streamId.StreamNameSize);
if (!BackupRead(hFile, hName.MemoryBlock, streamId.StreamNameSize, out bytesRead, false, false, ref context))
{
name = null;
finished = true;
}
else
{
// Unicode chars are 2 bytes:
name = hName.ReadStreamName(bytesRead >> 1);
}
}
// Add the stream info to the result:
if (!string.IsNullOrEmpty(name))
{
result.Add(new Win32StreamInfo
{
StreamType = (FileStreamType)streamId.StreamId,
StreamAttributes = (FileStreamAttributes)streamId.StreamAttributes,
StreamSize = streamId.Size.ToInt64(),
StreamName = name
});
}
// Skip the contents of the stream:
int bytesSeekedLow, bytesSeekedHigh;
if (!finished && !BackupSeek(hFile, streamId.Size.Low, streamId.Size.High, out bytesSeekedLow, out bytesSeekedHigh, ref context))
{
finished = true;
}
}
}
}
finally
{
// Abort the backup:
BackupRead(hFile, hName.MemoryBlock, 0, out bytesRead, true, false, ref context);
}
}
}
return result;
}
#endregion
}
}

View File

@@ -0,0 +1,134 @@
using System;
using System.Runtime.InteropServices;
namespace Trinet.Core.IO.Ntfs
{
internal sealed class StreamName : IDisposable
{
#region Private Data
private static readonly SafeHGlobalHandle _invalidBlock = SafeHGlobalHandle.Invalid();
private SafeHGlobalHandle _memoryBlock = _invalidBlock;
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="StreamName"/> class.
/// </summary>
public StreamName()
{
}
#endregion
#region Properties
/// <summary>
/// Returns the handle to the block of memory.
/// </summary>
/// <value>
/// The <see cref="SafeHGlobalHandle"/> representing the block of memory.
/// </value>
public SafeHGlobalHandle MemoryBlock
{
get { return _memoryBlock; }
}
#endregion
#region Methods
/// <summary>
/// Performs application-defined tasks associated with freeing,
/// releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (!_memoryBlock.IsInvalid)
{
_memoryBlock.Dispose();
_memoryBlock = _invalidBlock;
}
}
/// <summary>
/// Ensures that there is sufficient memory allocated.
/// </summary>
/// <param name="capacity">
/// The required capacity of the block, in bytes.
/// </param>
/// <exception cref="OutOfMemoryException">
/// There is insufficient memory to satisfy the request.
/// </exception>
public void EnsureCapacity(int capacity)
{
int currentSize = _memoryBlock.IsInvalid ? 0 : _memoryBlock.Size;
if (capacity > currentSize)
{
if (0 != currentSize) currentSize <<= 1;
if (capacity > currentSize) currentSize = capacity;
if (!_memoryBlock.IsInvalid) _memoryBlock.Dispose();
_memoryBlock = SafeHGlobalHandle.Allocate(currentSize);
}
}
/// <summary>
/// Reads the Unicode string from the memory block.
/// </summary>
/// <param name="length">
/// The length of the string to read, in characters.
/// </param>
/// <returns>
/// The string read from the memory block.
/// </returns>
public string ReadString(int length)
{
if (0 >= length || _memoryBlock.IsInvalid) return null;
if (length > _memoryBlock.Size) length = _memoryBlock.Size;
return Marshal.PtrToStringUni(_memoryBlock.DangerousGetHandle(), length);
}
/// <summary>
/// Reads the string, and extracts the stream name.
/// </summary>
/// <param name="length">
/// The length of the string to read, in characters.
/// </param>
/// <returns>
/// The stream name.
/// </returns>
public string ReadStreamName(int length)
{
string name = this.ReadString(length);
if (!string.IsNullOrEmpty(name))
{
// Name is of the format ":NAME:$DATA\0"
int separatorIndex = name.IndexOf(SafeNativeMethods.StreamSeparator, 1);
if (-1 != separatorIndex)
{
name = name.Substring(1, separatorIndex - 1);
}
else
{
// Should never happen!
separatorIndex = name.IndexOf('\0');
if (1 < separatorIndex)
{
name = name.Substring(1, separatorIndex - 1);
}
else
{
name = null;
}
}
}
return name;
}
#endregion
}
}

322
@integrate/WCFHost.cs Normal file
View File

@@ -0,0 +1,322 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Watchdog.WatchdogLib.Monitor;
using Watchdog.WatchdogLib.WinForms;
namespace Watchdog
{
/// <summary>
/// WCF Operations Contract in order to allow the command-line process
/// to communicate with the running Application's instance
/// </summary>
[ServiceContract]
public interface IWatchdog
{
#region Application State Changes
/// <summary>
/// Starts Monitoring
/// </summary>
[OperationContract]
void StartMonitoring();
/// <summary>
/// Pauses Monitoring
/// </summary>
[OperationContract]
void PauseMonitoring();
/// <summary>
/// Restarts Monitoring
/// </summary>
[OperationContract]
void RestartMonitoring();
/// <summary>
/// Restarts All Monitoring
/// </summary>
[OperationContract]
void RestartAllMonitoring();
/// <summary>
/// Stops Monitoring
/// </summary>
[OperationContract]
void StopMonitoring();
/// <summary>
/// Stops All Monitoring
/// </summary>
[OperationContract]
void StopAllMonitoring();
/// <summary>
/// Tell the Running Application to Reload the Configuration
/// </summary>
[OperationContract]
void ReloadConfigurationNextInterval();
#endregion
#region Ping
/// <summary>
/// To Check if we can communicate with the other side
/// </summary>
/// <returns>PING_RETURN_VALUE</returns>
[OperationContract]
int Ping();
#endregion
}
/// <summary>
/// Responsible for the WCF Callbacks
/// </summary>
public class WCFHost : IWatchdog
{
#region IWatchdog Members
/// <summary>
/// Starts Monitoring
/// </summary>
public void StartMonitoring()
{
HiddenMainWindow.StartMonitoring(true, true);
}
/// <summary>
/// Pauses Monitoring
/// </summary>
public void PauseMonitoring()
{
HiddenMainWindow.PauseMonitoring(true);
}
/// <summary>
/// Restarts Monitoring
/// </summary>
public void RestartMonitoring()
{
HiddenMainWindow.RestartMonitoring(4, true);
}
/// <summary>
/// Restarts All Monitoring
/// </summary>
public void RestartAllMonitoring()
{
HiddenMainWindow.RestartAllMonitoring(4, true);
}
/// <summary>
/// Stops Monitoring
/// </summary>
public void StopMonitoring()
{
HiddenMainWindow.StopMonitoring(true, false);
}
/// <summary>
/// Stops All Monitoring
/// </summary>
public void StopAllMonitoring()
{
HiddenMainWindow.StopAllMonitoring(true);
}
/// <summary>
/// Tell the Running Application to Reload the Configuration
/// </summary>
public void ReloadConfigurationNextInterval()
{
App.xmlfile.ForceRefreshOnNext_ReadData = true;
}
/// <summary>
/// Const Value to return on Ping
/// </summary>
public const int PING_RETURN_VALUE = 10;
/// <summary>
/// To Check if we can communicate with the other side
/// </summary>
/// <returns>PING_RETURN_VALUE</returns>
public int Ping()
{
return PING_RETURN_VALUE;
}
#endregion
#region Configuration Changes / Display Configuration Statics
/// <summary>
/// Adds a Process from the Configuration and saves the xml
/// </summary>
/// <param name="ProcessExeFileNameNPath">Process Exe File name</param>
/// <param name="CommandlinePrms">Command Line Prms for Process</param>
/// <param name="WorkingDir">Working Directory</param>
/// <returns>true if successfull, false otherwise</returns>
public static bool AddProcess(string ProcessExeFileNameNPath, string CommandlinePrms, string WorkingDir)
{
WatchdogConfiguration config = App.xmlfile.ReadData(false);
bool bSuccess = config.MonitoredProcesses.AddProcessExe(ProcessExeFileNameNPath, CommandlinePrms, WorkingDir);
if (bSuccess)
App.xmlfile.SaveData();
return bSuccess;
}
/// <summary>
/// Removes a Process from the Configuration and saves the xml
/// </summary>
/// <param name="ProcessExeFileNameNPath">Process Exe File name</param>
/// <param name="CommandlinePrms">Command Line Prms for Process</param>
/// <returns>true if successfully deleted a process with matching ProcessExeFileNameNPath and CommandlinePrms</returns>
public static bool RemoveProcess(string ProcessExeFileNameNPath, string CommandlinePrms)
{
WatchdogConfiguration config = App.xmlfile.ReadData(false);
bool bSuccess = config.MonitoredProcesses.RemoveProcessExe(ProcessExeFileNameNPath, CommandlinePrms);
if (bSuccess)
App.xmlfile.SaveData();
return bSuccess;
}
/// <summary>
/// Adds a Service from the configuration and saves the xml
/// </summary>
/// <param name="ServiceName">Name of Service</param>
/// <returns>true if sucessfull, false otherwise</returns>
public static bool AddService(string ServiceName)
{
WatchdogConfiguration config = App.xmlfile.ReadData(false);
bool bSuccess = config.MonitoredServices.AddServiceExe(ServiceName);
if (bSuccess)
App.xmlfile.SaveData();
return bSuccess;
}
/// <summary>
/// Removes a Service from the configuration and saves the xml
/// </summary>
/// <param name="ServiceName">Name of Service</param>
/// <returns>true if sucessfull, false otherwise</returns>
public static bool RemoveService(string ServiceName)
{
WatchdogConfiguration config = App.xmlfile.ReadData(false);
bool bSuccess = config.MonitoredServices.RemoveServiceExe(ServiceName);
if (bSuccess)
App.xmlfile.SaveData();
return bSuccess;
}
/// <summary>
/// Returns an array of all Processes and their configurations (in a ';' seperated string)
/// </summary>
/// <returns>Process List with configuration</returns>
public static string[] ShowProcesses()
{
List<string> ProcessList = new List<String>();
WatchdogConfiguration config = App.xmlfile.ReadData(false);
string s = String.Empty;
foreach (WatchdogConfiguration.ProcessExe p in config.MonitoredProcesses.ProcessExes)
{
if (String.IsNullOrEmpty(p.CommandLinePrms) && String.IsNullOrEmpty(p.WorkingDirectory))
s = p.ProcessExeFileNameNPath;
else if (!String.IsNullOrEmpty(p.CommandLinePrms) && String.IsNullOrEmpty(p.WorkingDirectory))
s = p.ProcessExeFileNameNPath + ";" + p.CommandLinePrms;
else if (!String.IsNullOrEmpty(p.CommandLinePrms) && !String.IsNullOrEmpty(p.WorkingDirectory))
s = p.ProcessExeFileNameNPath + ";" + p.CommandLinePrms + ";" + p.WorkingDirectory;
else
continue;
ProcessList.Add(s);
}
return ProcessList.ToArray();
}
/// <summary>
/// Returns an array of all Services
/// </summary>
/// <returns>Services List</returns>
public static string[] ShowServices()
{
List<string> ProcessList = new List<String>();
WatchdogConfiguration config = App.xmlfile.ReadData(false);
foreach (WatchdogConfiguration.ServiceExe s in config.MonitoredServices.ServiceExes)
ProcessList.Add(s.Name);
return ProcessList.ToArray();
}
#endregion
#region Internal Statics
private static ServiceHost _host = null;
/// <summary>
/// Start the WCF Pipe Host (Watchdog)
/// </summary>
internal static void StartHost()
{
// Make sure it is closed
StopHost();
_host = new ServiceHost(typeof(WCFHost), new Uri[] { new Uri("net.pipe://localhost") });
_host.AddServiceEndpoint(typeof(IWatchdog), new NetNamedPipeBinding(), AppResx.GetString("APPLICATION_NAME_SHORT"));
try
{
_host.Open();
}
catch (Exception e)
{
App.log.Fatal("Unable to start WCF Pipe Host", e);
MsgBox.ShowFatalError("Unable to start WCF Pipe Host", "Pipe Host Failure", System.Windows.Forms.MessageBoxButtons.OK);
App.Current.Shutdown();
}
}
/// <summary>
/// Stop the WCF Pipe Host
/// </summary>
internal static void StopHost()
{
if (_host != null)
{
_host.Close();
_host = null;
}
}
/// <summary>
/// Called by Client to communicate with the server
/// </summary>
/// <returns>a valid IWatchDog Object or Null if error occured</returns>
internal static IWatchdog GetWatchDogClientInterface()
{
// We only should be calling this in CommandLine Mode.
if (App.State_SpecialMode_IsCommandLineSet())
{
try
{
IWatchdog watchdoginterface = null;
ChannelFactory<IWatchdog> iwatchdogFactory = new ChannelFactory<IWatchdog>(new NetNamedPipeBinding(), new EndpointAddress(("net.pipe://localhost/" + AppResx.GetString("APPLICATION_NAME_SHORT"))));
watchdoginterface = iwatchdogFactory.CreateChannel();
// Try to ping the object! ~if it fails, target object doesn't exist
if (watchdoginterface.Ping() == WCFHost.PING_RETURN_VALUE)
return watchdoginterface;
}
catch (Exception)
{
// * Ignore this error we don't want to log this*
//App.log.Error("Failed to obtain WatchDogClientInterface", e);
}
}
return null;
}
#endregion
}
}

491
Assembly/AssemblyW.cs Normal file
View File

@@ -0,0 +1,491 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Refl = System.Reflection;
using System.Diagnostics;
using System.Reflection;
namespace Yaulw.Assembly
{
/// <remarks>
/// Useful Functions for Retrieving General Assembly Information
/// </remarks>
public static class AssemblyW
{
#region Assembly State/Type
/// <summary>
/// Assembly State/Type
/// </summary>
public enum AssemblyST
{
Calling,
Entry,
Executing
}
/// <summary>
/// Internal Helper Function to Get the Appropriate Assembly State/Type
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve</param>
/// <exception cref="ArgumentException">Thrown if invalist AssemblyST is passed in</exception>
/// <returns>Returns the Specified State/Type Assembly</returns>
private static Refl.Assembly GetAssembly(AssemblyST st)
{
switch (st)
{
case AssemblyST.Calling:
return Refl.Assembly.GetCallingAssembly();
case AssemblyST.Entry:
return Refl.Assembly.GetEntryAssembly();
case AssemblyST.Executing:
return Refl.Assembly.GetExecutingAssembly();
}
throw (new ArgumentException("Invalid AssemblyST"));
}
#endregion
#region Common Assembly Properties
/// <summary>
/// Returns the Name of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns 'just the Name' of the Assembly</returns>
public static string GetAssemblyName(AssemblyST st)
{
string[] curAsmName = GetAssembly(st).FullName.Split(',');
return curAsmName[0];
}
/// <summary>
/// Returns the Name of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns 'just the Name' of the Assembly</returns>
public static string GetAssemblyName(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
string[] curAsmName = asm.FullName.Split(',');
return curAsmName[0];
}
/// <summary>
/// Returns the Assembly Title
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns the Assembly Title, as specified in AssemblyInfo</returns>
public static string GetAssemblyTitle(AssemblyST st)
{
object[] attributes = GetAssembly(st).GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
return titleAttribute.Title;
}
return String.Empty;
}
/// <summary>
/// Returns the Assembly Title
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns the Assembly Title, as specified in AssemblyInfo</returns>
public static string GetAssemblyTitle(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
object[] attributes = asm.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
return titleAttribute.Title;
}
return String.Empty;
}
/// <summary>
/// Returns the Description of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns the Assembly Description, as specified in AssemblyInfo</returns>
public static string GetAssemblyDescription(AssemblyST st)
{
object[] attributes = GetAssembly(st).GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length > 0)
{
AssemblyDescriptionAttribute descriptionAttribute = (AssemblyDescriptionAttribute)attributes[0];
return descriptionAttribute.Description;
}
return String.Empty;
}
/// <summary>
/// Returns the Description of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns the Assembly Description, as specified in AssemblyInfo</returns>
public static string GetAssemblyDescription(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
object[] attributes = asm.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length > 0)
{
AssemblyDescriptionAttribute descriptionAttribute = (AssemblyDescriptionAttribute)attributes[0];
return descriptionAttribute.Description;
}
return String.Empty;
}
/// <summary>
/// Returns the Company Name of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns the Assembly Company, as specified in AssemblyInfo</returns>
public static string GetAssemblyCompany(AssemblyST st)
{
object[] attributes = GetAssembly(st).GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length > 0)
{
AssemblyCompanyAttribute companyAttribute = (AssemblyCompanyAttribute)attributes[0];
return companyAttribute.Company;
}
return String.Empty;
}
/// <summary>
/// Returns the Company Name of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns the Assembly Company, as specified in AssemblyInfo</returns>
public static string GetAssemblyCompany(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
object[] attributes = asm.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length > 0)
{
AssemblyCompanyAttribute companyAttribute = (AssemblyCompanyAttribute)attributes[0];
return companyAttribute.Company;
}
return String.Empty;
}
/// <summary>
/// Returns the Product Name of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns the Assembly Product, as specified in AssemblyInfo</returns>
public static string GetAssemblyProductName(AssemblyST st)
{
object[] attributes = GetAssembly(st).GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length > 0)
{
AssemblyProductAttribute productAttribute = (AssemblyProductAttribute)attributes[0];
return productAttribute.Product;
}
return String.Empty;
}
/// <summary>
/// Returns the Product Name of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns the Assembly Product, as specified in AssemblyInfo</returns>
public static string GetAssemblyProductName(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
object[] attributes = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length > 0)
{
AssemblyProductAttribute productAttribute = (AssemblyProductAttribute)attributes[0];
return productAttribute.Product;
}
return String.Empty;
}
/// <summary>
/// Returns the Copyright Information of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns the Assembly Copyright, as specified in AssemblyInfo</returns>
public static string GetAssemblyCopyright(AssemblyST st)
{
object[] attributes = GetAssembly(st).GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length > 0)
{
AssemblyCopyrightAttribute copyrightAttribute = (AssemblyCopyrightAttribute)attributes[0];
return copyrightAttribute.Copyright;
}
return String.Empty;
}
/// <summary>
/// Returns the Copyright Information of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns the Assembly Copyright, as specified in AssemblyInfo</returns>
public static string GetAssemblyCopyright(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
object[] attributes = asm.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length > 0)
{
AssemblyCopyrightAttribute copyrightAttribute = (AssemblyCopyrightAttribute)attributes[0];
return copyrightAttribute.Copyright;
}
return String.Empty;
}
/// <summary>
/// Returns the Assembly Version
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve</param>
/// <exception cref="ArgumentException">Thrown if invalist AssemblyST is passed in</exception>
/// <returns>Returns the Assembly Version, as specified in AssemblyInfo</returns>
public static Version GetAssemblyVersion(AssemblyST st)
{
return SpecializedAssemblyInfo.GetAssemblyNameObj(st).Version;
}
/// <summary>
/// Returns the Assembly Version
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalist Assembly is passed in</exception>
/// <returns>Returns the Assembly Version, as specified in AssemblyInfo</returns>
public static Version GetAssemblyVersion(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
return SpecializedAssemblyInfo.GetAssemblyNameObj(asm).Version;
}
/// <summary>
/// Returns the Assembly File Version
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve</param>
/// <exception cref="ArgumentException">Thrown if invalist AssemblyST is passed in</exception>
/// <returns>Returns the File Version, as specified by the File</returns>
public static FileVersionInfo GetAssemblyFileVersion(AssemblyST st)
{
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(SpecializedAssemblyInfo.GetAssemblyFileNameNPath(st));
return fvi;
}
/// <summary>
/// Returns the Assembly File Version
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalist Assembly is passed in</exception>
/// <returns>Returns the File Version, as specified by the File</returns>
public static FileVersionInfo GetAssemblyFileVersion(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(SpecializedAssemblyInfo.GetAssemblyFileNameNPath(asm));
return fvi;
}
#endregion
#region Specialized Assembly Information
/// <remarks>
/// Useful Functions for Retrieving Specialized Assembly Information
/// </remarks>
public class SpecializedAssemblyInfo
{
/// <summary>
/// Returns the Assembly Name Object from the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>AssemblyName object for the specified assembly</returns>
public static Refl.AssemblyName GetAssemblyNameObj(AssemblyST st)
{
return GetAssembly(st).GetName();
}
/// <summary>
/// Returns the Assembly Name Object from the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>AssemblyName object for the specified assembly</returns>
public static Refl.AssemblyName GetAssemblyNameObj(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
return asm.GetName();
}
/// <summary>
/// Returns the Exact File Name and Path of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Full File Name and Path</returns>
public static string GetAssemblyFileNameNPath(AssemblyST st)
{
Refl.Assembly asm = GetAssembly(st);
string curAsmName = asm.Location;
return curAsmName;
}
/// <summary>
/// Returns the Exact File Name and Path of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Full File Name and Path</returns>
public static string GetAssemblyFileNameNPath(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
string curAsmName = asm.Location;
return curAsmName;
}
/// <summary>
/// Returns the File Name (without Extension) of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>File Name without extension</returns>
public static string GetAssemblyFileName(AssemblyST st)
{
string curAsmName = Path.GetFileNameWithoutExtension(GetAssembly(st).ManifestModule.Name);
return curAsmName;
}
/// <summary>
/// Returns the File Name (without Extension) of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>File Name without extension</returns>
public static string GetAssemblyFileName(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
string curAsmName = Path.GetFileNameWithoutExtension(asm.ManifestModule.Name);
return curAsmName;
}
/// <summary>
/// Returns the Path of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Path</returns>
public static string GetAssemblyPath(AssemblyST st)
{
Refl.Assembly asm = GetAssembly(st);
string curAsmName = Path.GetDirectoryName(asm.Location);
return curAsmName;
}
/// <summary>
/// Returns the Path of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Path</returns>
public static string GetAssemblyPath(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
string curAsmName = Path.GetDirectoryName(asm.Location);
return curAsmName;
}
/// <summary>
/// Returns the File Name (with Extension) of the Assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>File Name with extension</returns>
public static string GetAssemblyFileNameWithExtension(AssemblyST st)
{
string curAsmName = Path.GetFileName(GetAssembly(st).ManifestModule.Name);
return curAsmName;
}
/// <summary>
/// Returns the File Name (with Extension) of the Assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>File Name with extension</returns>
public static string GetAssemblyFileNameWithExtension(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
string curAsmName = Path.GetFileName(asm.ManifestModule.Name);
return curAsmName;
}
/// <summary>
/// Returns all the Resource names inside the assembly
/// </summary>
/// <param name="st">State/Type of Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid AssemblyST is passed in</exception>
/// <returns>Returns all resource names defined in the assembly</returns>
public static string[] GetAssemblyResourceNames(AssemblyST st)
{
string[] resources = GetAssembly(st).GetManifestResourceNames();
return resources;
}
/// <summary>
/// Returns all the Resource names inside the assembly
/// </summary>
/// <param name="asm">Assembly to Retrieve Info for</param>
/// <exception cref="ArgumentException">Thrown if invalid Assembly is passed in</exception>
/// <returns>Returns all resource names defined in the assembly</returns>
public static string[] GetAssemblyResourceNames(Refl.Assembly asm)
{
if (asm == null)
throw new ArgumentException("Invalid Assembly");
string[] resources = asm.GetManifestResourceNames();
return resources;
}
}
#endregion
}
}

Binary file not shown.

BIN
Components/log4net.dll Normal file

Binary file not shown.

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace Yaulw.Encryption
{
/// <summary>
///
/// </summary>
public static class TextEncryptHash
{
private static byte[] _byteky = new byte[] {173,61,94,8,43,151,9,42,113,122,47,208,230,63,122,252,134,18,73,248,232,72,122,240,145,72,249,199,16,152,236,174,111,76,119,52,161,81,161,14,11,164,65,49,127,118,100,223,177,104,145,216,39,213,239,81,143,20,111,239,35,75,167,117};
public static string EncryptText(string text)
{
using (HMACSHA1 provider = new System.Security.Cryptography.HMACSHA1(_byteky, true))
{
//provider.En
}
return "";
}
}
}

287
File/CHMFile.cs Normal file
View File

@@ -0,0 +1,287 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using IO = System.IO;
using System.Windows.Forms;
using System.Windows;
using System.Windows.Interop;
using Yaulw.Process;
using Diag = System.Diagnostics;
namespace Yaulw.File
{
/// <summary>
/// CHM Help File Wrapper
/// </summary>
public class CHMFile
{
#region Private Members
/// <summary>
/// The Full File Name and Path to the CHM File
/// </summary>
private string _FileNameNPath = "";
/// <summary>
/// The File Stream that created the CHM File (if used)
/// </summary>
private IO.Stream _FileStream = null;
/// <summary>
/// Internally we keep track of each Form to Help Context ID
/// </summary>
private Dictionary<Form, int> s_FormContextMap = new Dictionary<Form, int>();
#endregion
#region Construction
/// <summary>
/// Construct a CHMFile object with the specified chm file
/// </summary>
/// <param name="FileNameNPath">a full path to a valid chm file</param>
public CHMFile(string FileNameNPath)
{
if (!String.IsNullOrEmpty(FileNameNPath) && IO.File.Exists(FileNameNPath) && (IO.Path.GetExtension(FileNameNPath).ToLower() == "chm"))
_FileNameNPath = FileNameNPath;
else
throw new ArgumentException("Invalid chm File or File does not exist");
}
/// <summary>
/// Construct a CHMFile object from the specified stream (will construct a chm file in
/// a temporary location from the specified stream)
/// </summary>
/// <param name="stream">stream to construct the chm file from</param>
/// <param name="ApplicationName">The name of the application (will be used when creating the .chm file)</param>
/// <param name="ForceNewFile">if true, will force a new file to be written out, false will only write file if not exists</param>
public CHMFile(IO.Stream stream, string ApplicationName, bool ForceNewFile)
{
if (stream != null && !String.IsNullOrEmpty(ApplicationName))
{
_FileStream = stream;
_FileNameNPath = IO.Path.GetTempPath() + ApplicationName + ".chm";
EnsureCHMFileExistance(ForceNewFile);
}
else
throw new ArgumentNullException("Resource can not be null. ApplicationName can not be empty");
}
#endregion
#region Public Consts
/// <summary>
/// Legacy MFC View Context offset
/// </summary>
public const int MNU = 0x10000;
/// <summary>
/// Legacy MFC Dialog Context offset
/// </summary>
public const int DLG = 0x20000;
#endregion
#region Public Methods
/// <summary>
/// Attaches the HelpRequest Handler as well as shows the HelpButton on the CaptionBar
/// </summary>
/// <param name="form">WinForm to Attach Help Button to</param>
/// <param name="dwContextId">the Help Topic Context Id to attach to the specified WinForm</param>
public void AttachHelpCaptionButtonToWinForm(Form form, int dwContextId)
{
// Set the HelpButton to be displayed
form.MinimizeBox = false;
form.MaximizeBox = false;
form.HelpButton = true;
// add the form / contextID to the map
s_FormContextMap[form] = (int)dwContextId;
// Subscribe to the Help Requested Handler
form.HelpRequested += new HelpEventHandler(form_HelpRequested);
// Subscribe to the Destroyed Event Handler *to remove the form from the list*
form.HandleDestroyed += new EventHandler(form_HandleDestroyed);
}
/// <summary>
/// Launch CHM Help
/// </summary>
public void LaunchHelp()
{
int bHelpIsAlreadyRunning_Pid = 0;
Diag.Process[] ps = ProcessW.AllRunningProcessesOf("hh", false, true);
if (ps != null && ps.Length >= 1)
{
foreach (Diag.Process p in ps)
{
string ProcessName = "";
string CommandLine = "";
ProcessW.GetCommandLineArgumentsForProcessPID(p.Id, out ProcessName, out CommandLine);
if (CommandLine.Contains(_FileNameNPath))
{
bHelpIsAlreadyRunning_Pid = p.Id;
break;
}
}
}
// No need to launch a second time
if (bHelpIsAlreadyRunning_Pid != 0)
{
// Set Focus
IntPtr hWnd = Yaulw.Win32.Functions.GetFirstTopLevelWindowForProcess(bHelpIsAlreadyRunning_Pid);
if (hWnd != IntPtr.Zero)
Yaulw.Win32.User32.SetActiveWindow(hWnd);
}
else
{
// Launch
EnsureCHMFileExistance(false);
PStarter.StartProcess(PStartInfo.CreateProcess(_FileNameNPath, "", "", false, System.Diagnostics.ProcessWindowStyle.Normal, true), false, false);
}
}
/// <summary>
/// Launch CHM Help
/// </summary>
/// <param name="form">form which will be the parent of the CHM File</param>
public void LaunchHelp(Form form)
{
if (form != null)
{
Control control = Control.FromHandle(form.Handle);
if (control != null)
{
EnsureCHMFileExistance(false);
Help.ShowHelp(control, _FileNameNPath);
}
}
}
/// <summary>
/// aunch CHM Help
/// </summary>
/// <param name="window">Window which will be the parent for the CHM file</param>
public void LaunchHelp(Window window)
{
if (window != null)
{
Control control = Control.FromHandle(GetHandleForWPFWindow(window));
if (control != null)
{
EnsureCHMFileExistance(false);
Help.ShowHelp(control, _FileNameNPath);
}
}
}
/// <summary>
/// Launch CHM Help for the specified Context
/// </summary>
/// <param name="form">form which will be the parent of the CHM File</param>
/// <param name="dwContextId">Context Id to launch chm file with</param>
public void LaunchHelp(Form form, int dwContextId)
{
if (form != null)
{
Control control = Control.FromHandle(form.Handle);
if (control != null)
{
EnsureCHMFileExistance(false);
Help.ShowHelp(control, _FileNameNPath, HelpNavigator.TopicId, dwContextId.ToString());
}
}
}
/// <summary>
/// aunch CHM Help for the specified Context
/// </summary>
/// <param name="window">Window which will be the parent for the CHM file</param>
/// <param name="dwContextId">Context Id to launch chm file with</param>
public void LaunchHelp(Window window, int dwContextId)
{
if (window != null)
{
EnsureCHMFileExistance(false);
Help.ShowHelp(null, _FileNameNPath, HelpNavigator.TopicId, dwContextId.ToString());
}
}
#endregion
#region Private WinForm Help Event Handlers
/// <summary>
/// Handle HelpRequests
/// </summary>
private void form_HelpRequested(object sender, HelpEventArgs hlpevent)
{
Form form = sender as Form;
if (form != null)
{
int dwContextId = s_FormContextMap[form];
Help.ShowHelp(form, _FileNameNPath, HelpNavigator.TopicId, dwContextId.ToString());
}
}
/// <summary>
/// Handle Form Destroys
/// </summary>
private void form_HandleDestroyed(object sender, EventArgs e)
{
Form form = sender as Form;
if (form != null)
s_FormContextMap.Remove(form);
}
#endregion
#region Private Helpers
/// <summary>
/// Creates the CHMFile from the stream (if a stream was used)
/// </summary>
/// <param name="ForceCreationOfFile">true to force re-creation of the file, false otherwise</param>
private void EnsureCHMFileExistance(bool ForceCreationOfFile)
{
if (_FileStream != null)
{
if (ForceCreationOfFile || !IO.File.Exists(_FileNameNPath))
{
using (IO.FileStream fs = new IO.FileStream(_FileNameNPath, IO.FileMode.Create))
{
using (IO.BinaryWriter writer = new IO.BinaryWriter(fs))
{
// Read from the Resource
Byte[] streamData = new Byte[_FileStream.Length];
_FileStream.Read(streamData, 0, streamData.Length);
// Write to File
writer.Write(streamData);
writer.Close();
}
}
}
}
}
/// <summary>
/// Uses the InteropHelper to get the Handle of a WPF Window
/// </summary>
/// <param name="window">a WPF Window</param>
/// <returns>an hWnd for the specified WPF Window</returns>
private IntPtr GetHandleForWPFWindow(Window window)
{
WindowInteropHelper InteropHelper = new WindowInteropHelper(window);
return InteropHelper.Handle;
}
#endregion
}
}

193
File/FileWriter.cs Normal file
View File

@@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Yaulw.File
{
/// <remarks>
/// Simple Line-By-Line UTF/Ascii File Writer Object
/// </remarks>
public class FileWriter
{
#region Private Members
private string _FileName = "";
private string _FileType = "";
private string _dirPath = "";
private bool _OverideExisting = false;
private bool _FileIsCreated = false;
#endregion
#region Construction
/// <summary>
/// Create a Simple UTF/Ascii Line FileWriter Object
/// </summary>
/// <param name="FileName">The Name of the File (If blank will generate a random file name)</param>
/// <param name="FileType">The Type of File to write to (Default = "log")</param>
/// <param name="dirPath">The path where to write the file (If Blank will use Temp Path)</param>
/// <param name="OverideExisting">true to overide an existing file, false will try to append by default</param>
public FileWriter(string FileName = "", string FileType = "log", string dirPath = "", bool OverideExisting = true)
{
_FileName = FileName;
_FileType = FileType;
_dirPath = dirPath;
_OverideExisting = OverideExisting;
// Generate File Name and Path, if not exist
if(String.IsNullOrEmpty(_FileName))
_FileName = System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetRandomFileName());
if(String.IsNullOrEmpty(_dirPath))
_dirPath = System.IO.Path.GetTempPath();
// Make Sure Path Exists
if (!Directory.Exists(_dirPath))
Directory.CreateDirectory(_dirPath);
}
#endregion
#region Write Ascii
/// <summary>
/// Write a Line in Ascii to File
/// </summary>
/// <param name="line">ascii line to write</param>
public void WriteLineA(string line)
{
using (FileStream fs = CreateFileStream())
using(StreamWriter sw = new StreamWriter(fs, Encoding.ASCII))
{
sw.WriteLine(line);
sw.Flush();
}
}
/// <summary>
/// Write Lines in Ascii to file
/// </summary>
/// <param name="lines">ascii lines to write</param>
public void WriteLineA(string[] lines)
{
using (FileStream fs = CreateFileStream())
using (StreamWriter sw = new StreamWriter(fs, Encoding.ASCII))
{
foreach (string line in lines)
sw.WriteLine(line);
sw.Flush();
}
}
#endregion
#region Write UTF
/// <summary>
/// Write a Line in UTF to File
/// </summary>
/// <param name="line">utf line to write</param>
public void WriteLineUTF8(string line)
{
using (FileStream fs = CreateFileStream())
using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
{
sw.WriteLine(line);
sw.Flush();
}
}
/// <summary>
/// Write Lines in UTF to File
/// </summary>
/// <param name="lines">utf lines to write</param>
public void WriteLineUTF8(string[] lines)
{
using (FileStream fs = CreateFileStream())
using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
{
foreach (string line in lines)
sw.WriteLine(line);
sw.Flush();
}
}
#endregion
#region Public Properties
/// <summary>
/// Returns the File Name
/// </summary>
public string FileName { get { return (this._FileName + "." + this._FileType); } }
/// <summary>
/// Returns the Path where the File is located
/// </summary>
public string Path { get { return (this._dirPath); } }
/// <summary>
/// Returns both Path and FileName
/// </summary>
public string FileNameNPath { get { return (this.Path + "\\" + this.FileName); } }
#endregion
#region Public Methods
/// <summary>
/// Deletes the File, if it exists
/// </summary>
/// <returns>true if successful, false otherwise</returns>
public bool DeleteFile()
{
try
{
if (System.IO.File.Exists(this.FileNameNPath))
{
System.IO.File.Delete(this.FileNameNPath);
_FileIsCreated = false;
return true;
}
}
catch (Exception) { /* ignore */ }
return false;
}
#endregion
#region Private Methods
/// <summary>
/// Creates the File Stream, either in Create or Append Mode
/// </summary>
/// <returns>a File Stream to Write to * Must be Closed by Caller *</returns>
private FileStream CreateFileStream()
{
try
{
bool bFileExists = System.IO.File.Exists(this.FileNameNPath);
if (!_FileIsCreated && _OverideExisting && bFileExists)
{
_FileIsCreated = true;
return (new FileStream(this.FileNameNPath, FileMode.Create));
}
else if (bFileExists)
{
return (new FileStream(this.FileNameNPath, FileMode.Append));
}
else
{
_FileIsCreated = true;
return (new FileStream(this.FileNameNPath, FileMode.Create));
}
}
catch (Exception) { /* ignore */ }
return null;
}
#endregion
}
}

213
File/INIFile.cs Normal file
View File

@@ -0,0 +1,213 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Yaulw.Tools;
using Yaulw.Win32;
using System.Diagnostics;
namespace Yaulw.File
{
/// <remarks>
/// Responsible for Reading and Writing an INI File.
/// Simply construct an INIFile Object passing in a File name and Path,
/// as well as an enum that lists all the Categories and Keys.
///
/// An example *You can mix and match Categories and Keys as needed *:
/// public enum INICatsNKeys
/// {
/// App_Settings__Load_XML_At_StartUp,
/// App_Settings__Allow_Command_Line_to_override_INI,
/// App_Settings__Default_User,
/// App_Settings__Default_Server,
/// Runtime_Debug__Error_Debug_Level,
/// Data_Access__Read_Only,
/// Settings__Program_Folder,
/// Settings__User1_Default,
/// Recent_File_List__File1,
/// Recent_File_List__File2,
/// Recent_File_List__File3,
/// Recent_File_List__File4,
/// }
///
/// The '__' Character signifies a category to Key change
/// the '_' will be replaced by ' ', when actually writing to the Ini File.
/// </remarks>
public class INIFile
{
#region Private Members
private string _IniPathNFileName = String.Empty;
private Type _IniKeysNCategories = null;
#endregion
#region Construction
/// <summary>
/// Initialize an INIFile object with a valid path and FileName to write/read from.
/// Also pass in an Enum Type that contains Category and Key Information. This Enum will be used
/// to read and write to the INIFile (to determine which Section/Key to read/write from/to)
/// </summary>
/// <param name="IniPathNFileName">Pass in the full file name and path to use * Creates Directory, if it does not exits *</param>
/// <param name="IniKeysNCategories">Pass in an Enum that specifies the Categories and Keys</param>
/// <exception cref="ArgumentException">Thrown if an invalid Enum is passed in via IniKeysNCategories</exception>
public INIFile(string IniPathNFileName, Type IniKeysNCategories)
{
// Check and ensure Enum Accuracy
if (IniKeysNCategories.IsEnum && EnumTool.EnumType_HasCategoryNKey(IniKeysNCategories))
{
_IniKeysNCategories = IniKeysNCategories;
}
else
throw new ArgumentException("IniKeysNCategories is not an Enum or not all Enums contain Key and Category Information");
// Ensure Directory Existence
if (!Directory.Exists(Path.GetDirectoryName(IniPathNFileName)))
Directory.CreateDirectory(Path.GetDirectoryName(IniPathNFileName));
_IniPathNFileName = IniPathNFileName;
}
#endregion
#region Public Properties
/// <summary>
/// Ini File Used by IniFile
/// </summary>
public string IniFile { get { return _IniPathNFileName; } }
#endregion
#region Public Ini Key Reader / Writer Functions
/// <summary>
/// Use this to directly set a key to any string value
/// </summary>
/// <param name="cKey">Specify Key and category set Directly</param>
/// <param name="Value">value to set</param>
/// <exception cref="ArgumentException">If cKey is not a valid Category/Key Pair Enum</exception>
public void SetKeyValue<T>(Enum cKey, T Value)
{
if (EnumTool.Enum_HasCategoryNKey(cKey))
{
string Category;
string Key;
EnumTool.Enum_ToCategoryNKey(cKey, out Category, out Key);
string ValueStr = ObjTool.ConvertObjToString<T>(Value);
SetKeyValueString(Category, Key, ValueStr);
}
else
{
throw new ArgumentException("cKey must have both Category and Key Information");
}
}
/// <summary>
/// Use this to directly retrieve a key
/// </summary>
/// <param name="cKey">Specify Key and category set Directly</param>
/// <param name="defaultValue">default value to return, if not found</param>
/// <returns>value retrieved or default value</returns>
/// <exception cref="ArgumentException">If cKey is not a valid Category/Key Pair Enum</exception>
public T GetKeyValue<T>(Enum cKey, T defaultValue)
{
try
{
if (EnumTool.Enum_HasCategoryNKey(cKey))
{
string Category;
string Key;
EnumTool.Enum_ToCategoryNKey(cKey, out Category, out Key);
// Get Key and verify that something was found
string defaultValueStr = ObjTool.ConvertObjToString<T>(defaultValue);
string KeyValue = GetKeyValueString(Category, Key, defaultValueStr);
bool bHasAValue = (KeyValue.Trim().Length != 0);
// always write the value back out to ini
SetKeyValue(cKey, bHasAValue ? KeyValue : defaultValueStr);
// Return value
if (bHasAValue)
{
return ObjTool.ConvertStringToObj<T>(KeyValue);
}
else
{
return defaultValue;
}
}
else
{
throw new ArgumentException("cKey must have both Category and Key Information");
}
}
catch (Exception) { /* ignore */ }
return defaultValue;
}
#endregion
#region Private Generic Ini Key Reader / Writer Functions
/// <summary>
/// Set a value for the specified Key and for the specified category
/// </summary>
/// <param name="category">specify category</param>
/// <param name="key">specify key</param>
/// <param name="value">specify a value to set</param>
private void SetKeyValueString(string category, string key, string value)
{
bool bSuccess = Kernel32.WritePrivateProfileString(category, key, value, IniFile);
Debug.Assert(bSuccess);
}
/// <summary>
/// Retrieve the value for a specified Key and for a specified category
/// </summary>
/// <param name="category">specify category</param>
/// <param name="key">specify key</param>
/// <param name="defaultValue">specify default value, returned when no value found</param>
/// <returns>the value for the Key, or default value if no value found</returns>
private string GetKeyValueString(string category, string key, string defaultValue)
{
StringBuilder returnString = new StringBuilder(1024);
Kernel32.GetPrivateProfileString(category, key, defaultValue, returnString, 1024, IniFile);
return returnString.ToString().Split('\0')[0];
}
#endregion
#region Private Generic Ini File Readers (Not Used)
/// <summary>
/// Use this to return all the categories in an INI File
/// </summary>
/// <returns>a list with Gategory Items, or 0 length list is none found</returns>
private List<string> GetAllCategories()
{
StringBuilder returnString = new StringBuilder(65536);
uint returnValue = Kernel32.GetPrivateProfileString(null, null, null, returnString, 65536, IniFile);
List<string> result = new List<string>(returnString.ToString().Split('\0'));
result.RemoveRange(result.Count - 2, 2);
return result;
}
/// <summary>
/// Use this to return the Keys from a category from an INI File
/// </summary>
/// <returns>a list with Key Items, or 0 length list is none found</returns>
private List<string> GetAllKeysInCategory(string category)
{
StringBuilder returnString = new StringBuilder(32768);
Kernel32.GetPrivateProfileString(category, null, null, returnString, 32768, IniFile);
List<string> result = new List<string>(returnString.ToString().Split('\0'));
result.RemoveRange(result.Count - 2, 2);
return result;
}
#endregion
}
}

185
File/ISReadWrite.cs Normal file
View File

@@ -0,0 +1,185 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.IsolatedStorage;
using System.IO;
using System.Reflection;
namespace Yaulw.File
{
/// <summary>
///
/// </summary>
public enum ISScope
{
User,
Machine,
}
/// <summary>
/// Class allows reading and writing to isolated Storage
/// </summary>
public class ISReadWrite
{
#region Private Members
private string _ISOLATED_STORAGE_FILENAME = "";
private bool _bFileInIsoStoreExists = false;
private Xml.XSerializer _XSerializer = null;
private IsolatedStorageScope _scope = IsolatedStorageScope.None;
private IsolatedStorageFile _isoStore = null;
#endregion
#region Construction
/// <summary>
///
/// </summary>
/// <param name="ISFileName"></param>
public ISReadWrite(string ISFileName) : this(ISFileName, ISScope.Machine) { }
/// <summary>
///
/// </summary>
/// <param name="ISFileName"></param>
/// <param name="scope"></param>
public ISReadWrite(string ISFileName, ISScope scope)
{
_ISOLATED_STORAGE_FILENAME = ISFileName;
if (String.IsNullOrEmpty(_ISOLATED_STORAGE_FILENAME))
throw new ArgumentNullException("ISFileName can not be empty.");
#if NET4
if (!IsolatedStorageFile.IsEnabled)
throw new Exception("Isolated Storage not enabled");
#endif
_scope = ConvertISScopeToIsolatedStorageScope(scope);
_isoStore = IsolatedStorageFile.GetStore(_scope, typeof(System.Security.Policy.Url), typeof(System.Security.Policy.Url));
_bFileInIsoStoreExists = (_isoStore.GetFileNames(ISFileName).Length > 0);
_XSerializer = new Xml.XSerializer();
}
#endregion
#region Public Read / Write Methods
public string ReadFromIS()
{
using (IsolatedStorageFileStream fs = new IsolatedStorageFileStream(_ISOLATED_STORAGE_FILENAME, FileMode.OpenOrCreate, _isoStore))
using (StreamReader reader = new StreamReader(fs))
{
_bFileInIsoStoreExists = true;
string strFileContents = reader.ReadToEnd();
if (!String.IsNullOrEmpty(strFileContents))
return strFileContents;
}
return String.Empty;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T ReadFromIS<T>()
{
using (IsolatedStorageFileStream fs = new IsolatedStorageFileStream(_ISOLATED_STORAGE_FILENAME, FileMode.OpenOrCreate, _isoStore))
using (StreamReader reader = new StreamReader(fs))
{
_bFileInIsoStoreExists = true;
string strFileContents = reader.ReadToEnd();
if (!String.IsNullOrEmpty(strFileContents))
{
T t = _XSerializer.ReadFromString<T>(strFileContents);
return t;
}
}
return default(T);
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="SerializableObject"></param>
public void WriteToIS<T>(T XMLSerializableObject) where T : new()
{
using (IsolatedStorageFileStream fs = new IsolatedStorageFileStream(_ISOLATED_STORAGE_FILENAME, FileMode.Create, _isoStore))
using (StreamWriter writer = new StreamWriter(fs))
{
_bFileInIsoStoreExists = true;
string strFileContentsToWrite = _XSerializer.WriteToString<T>(XMLSerializableObject);
if(!String.IsNullOrEmpty(strFileContentsToWrite))
writer.Write(strFileContentsToWrite);
}
}
/// <summary>
///
/// </summary>
public void WriteToIS(string Content)
{
using (IsolatedStorageFileStream fs = new IsolatedStorageFileStream(_ISOLATED_STORAGE_FILENAME, FileMode.Create, _isoStore))
using (StreamWriter writer = new StreamWriter(fs))
{
_bFileInIsoStoreExists = true;
string strFileContentsToWrite = Content;
if (!String.IsNullOrEmpty(strFileContentsToWrite))
writer.Write(strFileContentsToWrite);
}
}
#endregion
#region Public Methods
/// <summary>
///
/// </summary>
public void Delete()
{
if (_bFileInIsoStoreExists)
{
_isoStore.DeleteFile(_ISOLATED_STORAGE_FILENAME);
_bFileInIsoStoreExists = false;
}
}
#endregion
#region Public Properties
public bool Exists
{
get { return _bFileInIsoStoreExists; }
}
#endregion
#region Private Helpers
/// <summary>
///
/// </summary>
/// <param name="scope"></param>
/// <returns></returns>
private IsolatedStorageScope ConvertISScopeToIsolatedStorageScope(ISScope scope)
{
switch (scope)
{
case ISScope.User:
return IsolatedStorageScope.User | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly;
case ISScope.Machine:
return IsolatedStorageScope.Machine | IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly;
}
return IsolatedStorageScope.Application;
}
#endregion
}
}

172
File/LineReplacer.cs Normal file
View File

@@ -0,0 +1,172 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IO = System.IO;
namespace Yaulw.File
{
#region Rule Definitions
/// <summary>
/// Comparer Modifier used when looking at the line
/// </summary>
public enum LineReplace_ComparerModifier
{
None,
toLower,
toUpper,
}
/// <summary>
/// Rule Used to determine which line to replace
/// ~Replace Line with contains the new line to put instead
/// </summary>
public struct LineReplace_Rule
{
public string Contains;
public string StartsWith;
public string EndsWith;
public LineReplace_ComparerModifier Comparer;
public string ReplaceLineWith;
}
#endregion
/// <summary>
/// Useful for replacing lines in a text file.
/// It reads in a text file line by line and compares the lines.
/// Using the rules you can replace a line or multiple lines and write out to the text file.
/// </summary>
public class LineReplacer
{
#region Private Members
private Dictionary<String, LineReplace_Rule> _RulesDictionary = new Dictionary<string, LineReplace_Rule>();
private string _fileNameNPath = "";
private Encoding _encoding = Encoding.UTF8;
#endregion
#region Construction
/// <summary>
/// Allows for easy line replacing of a text file
/// </summary>
/// <param name="FileNameNPath">Full File Name and Path to a file that exists</param>
/// <exception cref="ArgumentException">Thrown when File does not exist</exception>
public LineReplacer(string FileNameNPath, Encoding encoding)
{
if (String.IsNullOrEmpty(FileNameNPath) || !IO.File.Exists(FileNameNPath))
throw new ArgumentException("Line Replace makes only sense on Files that exist already");
_fileNameNPath = FileNameNPath;
_encoding = encoding;
}
#endregion
#region Public Methods
/// <summary>
/// Add/Update Line Replacing Rules into here BEFORE calling ReplaceLines()
/// </summary>
/// <param name="RuleName">unique name of the rule</param>
/// <param name="rule">Rule Definition</param>
/// <returns>true if successfully added, false otherwise</returns>
public bool AddUpdateRule(string RuleName, LineReplace_Rule rule)
{
if (!String.IsNullOrEmpty(RuleName))
{
// We must be able to match on something
if (String.IsNullOrEmpty(rule.StartsWith) && String.IsNullOrEmpty(rule.EndsWith) &&
String.IsNullOrEmpty(rule.Contains))
return false;
// We must be able to replace with something
if (String.IsNullOrEmpty(rule.ReplaceLineWith))
return false;
// Rule is good, add it
_RulesDictionary[RuleName] = rule;
}
return false;
}
/// <summary>
/// Call this Function to Replace all the Lines of the Text Files that
/// match a specific Rule
/// </summary>
public void ReplaceLines()
{
if (_RulesDictionary.Count <= 0)
return;
// # Readin and Process all Lines
List<string> ReadInLines = new List<string>();
using (IO.FileStream fs = new IO.FileStream(_fileNameNPath, IO.FileMode.Open))
using (IO.StreamReader reader = new IO.StreamReader(fs, _encoding))
{
// # Iterate thru all the lines in the File
for (string Line = reader.ReadLine(); Line != null; Line = reader.ReadLine())
{
FoundRuleMathAndPerformedAction(ref Line);
ReadInLines.Add(Line);
}
}
// # Write out all the Lines
using (IO.FileStream fs = new IO.FileStream(_fileNameNPath, IO.FileMode.Create))
using (IO.StreamWriter writer = new IO.StreamWriter(fs, _encoding))
{
foreach (string Line in ReadInLines)
writer.WriteLine(Line);
}
}
#endregion
#region Private Helpers
/// <summary>
/// Responsible for finding a match between a line and a rule and
/// performing the action
/// </summary>
/// <param name="Line">Line to find a match for</param>
/// <returns>true, if match was found/action was done, false otherwise</returns>
private bool FoundRuleMathAndPerformedAction(ref string Line)
{
if (String.IsNullOrEmpty(Line))
return false;
bool bFoundMatch = false;
// Iterate foreach rule for a line
foreach (LineReplace_Rule rule in _RulesDictionary.Values)
{
// Make sure to use the proper comparer Modifier for the rule
string line = Line;
if (rule.Comparer == LineReplace_ComparerModifier.toLower)
line = Line.ToLower();
else if (rule.Comparer == LineReplace_ComparerModifier.toUpper)
line = Line.ToUpper();
// Now let's match on the actual Rule
if (!bFoundMatch && !String.IsNullOrEmpty(rule.StartsWith))
bFoundMatch = line.StartsWith(rule.StartsWith);
if (!bFoundMatch && !String.IsNullOrEmpty(rule.EndsWith))
bFoundMatch = line.StartsWith(rule.EndsWith);
if (!bFoundMatch && !String.IsNullOrEmpty(rule.Contains))
bFoundMatch = line.StartsWith(rule.Contains);
if (bFoundMatch)
{
Line = rule.ReplaceLineWith;
break;
}
}
return bFoundMatch;
}
#endregion
}
}

176
File/LoggerQuick.cs Normal file
View File

@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Yaulw.Assembly;
namespace Yaulw.File
{
/// <summary>
/// Easy Class for quick and dirty logging *that can automatically on a daily basis*
/// </summary>
public class LoggerQuick
{
#region Private Members
/// <summary>
/// FileWriter Object
/// </summary>
private Yaulw.File.FileWriter _fileWriter = null;
/// <summary>
/// Current Directory
/// </summary>
private string _curPath = "";
/// <summary>
/// Log Debug Messages
/// </summary>
private bool _LogDebug = false;
/// <summary>
/// Name of the Log (also serves as RegKey)
/// </summary>
private string LogName = "";
#endregion
#region Construction
/// <summary>
/// Quick Logger (which can clear itself daily and has no dependencies)
/// quick n' dirty logs in the current directory from which it is called
/// </summary>
/// <param name="LogName">Name of the Log file</param>
/// <param name="bLogDebugMessages">true to spit out DebugMessages, false otherwise</param>
public LoggerQuick(string LogName, bool bLogDebugMessages)
{
if(String.IsNullOrEmpty(LogName))
throw new ArgumentException("LogName can't be empty");
// Log Name, which will also server as the registry key name
this.LogName = Path.GetFileName(LogName);
// Log Debug Messages?
_LogDebug = bLogDebugMessages;
// Get the current running directory
if (String.IsNullOrEmpty(_curPath))
_curPath = Path.GetDirectoryName(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileNameNPath(AssemblyW.AssemblyST.Executing));
// Set up FileWriter
if (_fileWriter == null)
_fileWriter = new Yaulw.File.FileWriter(LogName, "log", _curPath, false);
}
/// <summary>
/// Quick Logger (which can clear itself daily and has no dependencies)
/// quick n' dirty logs in the current directory from which it is called
/// </summary>
/// <param name="LogName">Name of the Log file</param>
/// <param name="bLogDebugMessages">true to spit out DebugMessages, false otherwise</param>
/// <param name="path">path to log to</param>
public LoggerQuick(string LogName, bool bLogDebugMessages, string path)
{
if (String.IsNullOrEmpty(LogName))
throw new ArgumentException("LogName can't be empty");
// Log Name, which will also server as the registry key name
this.LogName = Path.GetFileName(LogName);
// Log Debug Messages?
_LogDebug = bLogDebugMessages;
// make sure path is valid
try
{
if (!String.IsNullOrEmpty(path))
{
path = Path.GetDirectoryName(path);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}
}
catch (Exception) { /* ignore */ }
// Get the current running directory
if (String.IsNullOrEmpty(_curPath) && String.IsNullOrEmpty(path))
_curPath = Path.GetDirectoryName(AssemblyW.SpecializedAssemblyInfo.GetAssemblyFileNameNPath(AssemblyW.AssemblyST.Executing));
else
_curPath = path;
// Set up FileWriter
if (_fileWriter == null)
_fileWriter = new Yaulw.File.FileWriter(LogName, "log", _curPath, false);
}
#endregion
#region Public Log Methods
/// <summary>
/// Debug Logging only logs when _LogDebug is set
/// </summary>
/// <param name="line"></param>
/// <param name="args"></param>
public void Debug(string line, params object[] args)
{
if (_LogDebug)
Log("Debug: ", line, args);
}
/// <summary>
/// Info Logging
/// </summary>
/// <param name="line"></param>
/// <param name="args"></param>
public void Info(string line, params object[] args)
{
Log("Info: ", line, args);
}
/// <summary>
/// Error Logging
/// </summary>
/// <param name="line"></param>
/// <param name="args"></param>
public void Error(string line, params object[] args)
{
Log("Error: ", line, args);
}
#endregion
#region Private Log Methods
/// <summary>
/// Used for logging * Medisoft people * crack me up
/// </summary>
/// <param name="line"></param>
/// <param name="ars"></param>
private void Log(string prePrend, string line, params object[] args)
{
if (_fileWriter != null)
{
// Clear the log once a day automatically - yeah!
DateTime LastLogged = Yaulw.Registry.RegKey.GetKey<DateTime>("LoggerQuick", LogName, DateTime.MinValue);
if (LastLogged != DateTime.MinValue && LastLogged.Day != DateTime.Now.Day)
_fileWriter.DeleteFile();
// Always set the DT Stamp, for every log
Yaulw.Registry.RegKey.SetKey<DateTime>("LoggerQuick", LogName, DateTime.Now);
// Now let's start Logging
line = prePrend + line;
if (args != null)
_fileWriter.WriteLineA(String.Format(line, args));
else
_fileWriter.WriteLineA(line);
}
}
#endregion
}
}

391
File/Logging.cs Normal file
View File

@@ -0,0 +1,391 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Diag = System.Diagnostics;
// Log4Net Declarations
using log4net.Appender;
using log4net.Core;
using log4net.Layout;
using log4net.Config;
using log4net;
using Yaulw.Other;
namespace Yaulw.File
{
/// <summary>
/// Logging Detail
/// </summary>
public enum Logging_Detail
{
NONE,
ERROR,
INFO,
DEBUG
}
/// <summary>
/// Used to Configure a Logger Instance in the Logging Class via AddGlobalLoggerConfiguration()
/// <example>
/// <code>
/// Logging_Configuration config;
/// config.LogFileNameNPath = "c:\\LogFile.log";
/// config.Detail = Logging_Detail.Error;
/// config.UseExclusiveFileLock = false;
/// config.maxFileSizeInMB = 4;
/// config.numOfBackupLogFiles = 3;
/// config.Log4NetDetailPatternLayout = "%date{dd MMM HH:mm:ss,fff} [%thread] %level - %message%newline"; (Default)
/// "%date{dd MMM yyyy HH:mm:ss,fff} [%thread] %level %logger - %message%newline";
/// config.LogCallingTypeAndCallingFunction = true;
/// </code>
/// </example>
/// </summary>
public struct Logging_Configuration
{
public string LogFileNameNPath;
public Logging_Detail Detail;
public bool UseExclusiveFileLock;
public int maxFileSizeInMB;
public int numOfBackupLogFiles;
public string Log4NetDetailPatternLayout;
public bool LogCallingType;
public bool LogCallingFunction;
}
/// <remarks>
/// Is a Wrapper Object around Log4Net's Rolling File Appender.
/// Use it by calling AddGlobalLoggerConfiguration() with a valid Logging Configuration.
/// You can configure multipe Logger Instances distinguished by Name.
/// subsequent calls can call GetLogger() with the named Logger instance to receive a valid logger object
/// </remarks>
public class Logging
{
#region Private Static Members
private static Dictionary<string, Logging_Configuration> _loggerConfigurationMap = new Dictionary<string, Logging_Configuration>();
private static Dictionary<string, ILog> _loggerObjects = new Dictionary<string, ILog>();
// If this process is hosted in VS then it changes the stack frame
private static bool s_IsVSHosted = false;
#endregion
#region Private Construction
/// <summary>
/// Private Constructor should only be called by static GetLogger() Function
/// </summary>
/// <param name="bLogCallingTypeAndCallingFunction">if true, will log calling type and Calling Function</param>
private Logging(bool bLogCallingType, bool bLogCallingFunction)
{
s_IsVSHosted = Diag.Process.GetCurrentProcess().ProcessName.Contains("vshost");
_LogCallingType = bLogCallingType;
_LogCallingFunction = bLogCallingFunction;
}
#endregion
#region Internal Members
// Initialized by GetLogger()
internal ILog _Log4NetLog = null;
// Initialized by GetLogger()
internal bool _LogCallingType = false;
// Initialized by GetLogger()
internal bool _LogCallingFunction = false;
#endregion
#region Public Log Methods
/// <summary>
/// Log Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Info(string message, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Info(MessageHeader() + String.Format(message, args)); } }
/// <summary>
/// Log Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Info(string message, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Info(MessageHeader(nPlusMinus) + String.Format(message, args)); } }
/// <summary>
/// Log Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Info(string message, Exception exception, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Info(MessageHeader() + String.Format(message, args), exception); } }
/// <summary>
/// Log Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Info(string message, Exception exception, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Info(MessageHeader(nPlusMinus) + String.Format(message, args), exception); } }
/// <summary>
/// Log Debug Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Debug(string message, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Debug(MessageHeader() + String.Format(message, args)); } }
/// <summary>
/// Log Debug Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Debug(string message, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Debug(MessageHeader(nPlusMinus) + String.Format(message, args)); } }
/// <summary>
/// Log Debug Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Debug(string message, Exception exception, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Debug(MessageHeader() + String.Format(message, args), exception); } }
/// <summary>
/// Log Debug Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Debug(string message, Exception exception, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Debug(MessageHeader(nPlusMinus) + String.Format(message, args), exception); } }
/// <summary>
/// Log Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Error(string message, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Error(MessageHeader() + String.Format(message, args)); } }
/// <summary>
/// Log Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Error(string message, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Error(MessageHeader(nPlusMinus) + String.Format(message, args)); } }
/// <summary>
/// Log Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Error(string message, Exception exception, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Error(MessageHeader() + String.Format(message, args), exception); } }
/// <summary>
/// Log Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Error(string message, Exception exception, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Error(MessageHeader(nPlusMinus) + String.Format(message, args), exception); } }
/// <summary>
/// Log Fatal Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Fatal(string message, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Fatal(MessageHeader() + String.Format(message, args)); } }
/// <summary>
/// Log Fatal Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Fatal(string message, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Fatal(MessageHeader(nPlusMinus) + String.Format(message, args)); } }
/// <summary>
/// Log Fatal Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Fatal(string message, Exception exception, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Fatal(MessageHeader() + String.Format(message, args), exception); } }
/// <summary>
/// Log Fatal Error Information
/// </summary>
/// <param name="message">Message to write</param>
/// <param name="exception">Exception to Log</param>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <param name="args">arguments to pass to String.Format</param>
public void Fatal(string message, Exception exception, int nPlusMinus, params object[] args) { if (_Log4NetLog != null) { _Log4NetLog.Fatal(MessageHeader(nPlusMinus) + String.Format(message, args), exception); } }
/// <returns>
/// Message Header to be shown on every log message
/// </returns>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
private string MessageHeader(int nPlusMinus = 0)
{
// When Running this from via VS it behaves differently then when
// running it outside of it, when running it regularly, each foreach loop
if (s_IsVSHosted)
{
if (_LogCallingType && _LogCallingFunction)
return StackWalker.GetTypeFromStack(nPlusMinus + 1) + " - " + StackWalker.GetMethodNameFromStack(nPlusMinus + 1) + "()- ";
else if (_LogCallingFunction)
return StackWalker.GetMethodNameFromStack(nPlusMinus + 1) + "()- ";
else
return "";
}
else
{
if (_LogCallingType && _LogCallingFunction)
return StackWalker.GetTypeFromStack(nPlusMinus) + " - " + StackWalker.GetMethodNameFromStack(nPlusMinus) + "()- ";
else if (_LogCallingFunction)
return StackWalker.GetMethodNameFromStack(nPlusMinus) + "()- ";
else
return "";
}
}
#endregion
#region Public Static Configuration and Logger Creation Methods
/// <summary>
/// Used to add a new Configuration and Logger Instance onto a Static Map.
/// Will create one logger instance per unique name.
/// </summary>
/// <param name="Name">a name for the logger instance</param>
/// <param name="Configuration">a valid configuration to use on the instance</param>
/// <returns>a logging object that can be used to log</returns>
public static Logging AddGlobalLoggerConfiguration(string Name, Logging_Configuration Configuration)
{
// Must have a Valid Input
if (string.IsNullOrEmpty(Name))
throw new ArgumentException("Name Is Invalid");
if (!_loggerObjects.Keys.Contains(Name.ToLower()))
{
// Create the Repository
log4net.Repository.ILoggerRepository repository = LogManager.CreateRepository(Name.ToLower());
// Create FileAppender Configuration
RollingFileAppender appender = RollingFileAppenderCreator(Configuration);
// Run the Configuration against the Repository
BasicConfigurator.Configure(repository, appender);
// Add Configuration to our Static Map
_loggerConfigurationMap[Name.ToLower()] = Configuration;
// Last, but not least, Create the new Logging Instance Object and Store it
_loggerObjects[Name.ToLower()] = LogManager.GetLogger(Name.ToLower(), Name.ToLower());
}
// Let the Caller get the Logging Object
return GetLogger(Name);
}
/// <summary>
/// Used to retrieve a named logging instance that has already been created via a previous call
/// to AddGlobalLoggerConfiguration().
/// </summary>
/// <param name="Name">a name for a previously created Logging instance</param>
/// <returns>a Logging object that can be used to log</returns>
public static Logging GetLogger(string Name)
{
if (_loggerObjects.Keys.Contains(Name.ToLower()) && _loggerConfigurationMap.Keys.Contains(Name.ToLower()))
{
bool bLogCallingType = _loggerConfigurationMap[Name.ToLower()].LogCallingType;
bool bLogCallingFunction = _loggerConfigurationMap[Name.ToLower()].LogCallingFunction;
Logging logger = new Logging(bLogCallingType, bLogCallingFunction);
logger._Log4NetLog = _loggerObjects[Name.ToLower()];
return logger;
}
else
throw new ArgumentException("Must call AddGlobalLoggerConfiguration() with a Configuration Before calling this Function");
}
#endregion
#region Private Static Helper Methods
/// <summary>
/// Creates a Log4Net RollingFileAppender with the specified configuration
/// </summary>
/// <param name="config">a valid configuration</param>
/// <returns>a Log4Net RollingFileAppender Object</returns>
private static RollingFileAppender RollingFileAppenderCreator(Logging_Configuration config)
{
#region Input Validation
if (config.maxFileSizeInMB <= 0)
throw new ArgumentException("Logging_Configuration - Invalid maxFileSizeInMB");
if (config.numOfBackupLogFiles < 0)
throw new ArgumentException("Logging_Configuration - Invalid numOfBackupLogFiles");
if (String.IsNullOrEmpty(config.LogFileNameNPath))
throw new Exception("Logging_Configuration - Invalid LogFileNameNPath");
if (!Directory.Exists(Path.GetDirectoryName(config.LogFileNameNPath)))
Directory.CreateDirectory(Path.GetDirectoryName(config.LogFileNameNPath));
#endregion
// Create and Set Layout for FileAppender
RollingFileAppender rfAppender = new RollingFileAppender();
// Set Layout
if (!String.IsNullOrEmpty(config.Log4NetDetailPatternLayout))
rfAppender.Layout = new PatternLayout(config.Log4NetDetailPatternLayout);
else
rfAppender.Layout = new PatternLayout("%date{dd MMM HH:mm:ss,fff} [%thread] %level - %message%newline");
// Locking Minimal allows us to run Log4Net from multiple processes
if (config.UseExclusiveFileLock)
rfAppender.LockingModel = new FileAppender.ExclusiveLock();
else
rfAppender.LockingModel = new FileAppender.MinimalLock();
// Configure FileName and always set Appent to true
rfAppender.File = config.LogFileNameNPath;
rfAppender.AppendToFile = true;
// According to the listings on the blog site
// http://blog.aggregatedintelligence.com/2009/08/log4net-logging-levels-available.html
// Error, will log Error, Fatal
// Info, will log Info, Error, and Fatal
// Debug, will log Info, Error, Fatal and Debug
if (config.Detail == Logging_Detail.NONE)
rfAppender.Threshold = Level.Off;
else if (config.Detail == Logging_Detail.ERROR)
rfAppender.Threshold = Level.Error;
else if (config.Detail == Logging_Detail.INFO)
rfAppender.Threshold = Level.Info;
else if (config.Detail == Logging_Detail.DEBUG)
rfAppender.Threshold = Level.Debug;
rfAppender.MaximumFileSize = String.Format("{0}MB", config.maxFileSizeInMB);
rfAppender.MaxSizeRollBackups = config.numOfBackupLogFiles;
// Setting to RollingMode.Size will make MaxSizeRollBackups work
rfAppender.RollingStyle = RollingFileAppender.RollingMode.Size;
rfAppender.ActivateOptions();
return rfAppender;
}
#endregion
}
}

190
File/Tail.cs Normal file
View File

@@ -0,0 +1,190 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Yaulw.File
{
/// <remarks>
/// A File SystemWatcher utility that functions like the infamous unix tail utility,
/// with a callback when the file get's created or updated.
/// </remarks>
public class Tail
{
#region Public Events
/// <summary>
/// Event Delegate for the Incoming Data Event
/// </summary>
/// <param name="sender">object reference to the sending Tail Object</param>
/// <param name="newData">change data / or full data if bIsNewFile is true</param>
/// <param name="bIsNewFile">true if a new file was created</param>
public delegate void IncomingDataHandler(object sender, string newData, bool bIsNewFile);
/// <summary>
/// Caller must subscribe to the Incoming Data Event
/// </summary>
public event IncomingDataHandler IncomingData = null;
#endregion
#region Private Members
private string _FileNameNPath = "";
private FileSystemWatcher _fileSystemWatcher = null;
private long _previousSeekPosition = 0;
private object _lockingObj = new Object();
private const int MAX_BYTE_TO_READ_IN_ONE_TIME = 1024 * 16;
#endregion
#region Construction
/// <summary>
/// Construct a new Tail Object to monitor the specified file
/// </summary>
/// <param name="FileNameNPath">File to Monitor with Tail</param>
public Tail(string FileNameNPath)
{
_previousSeekPosition = 0;
_FileNameNPath = FileNameNPath;
}
#endregion
#region Public Methods
/// <summary>
/// Start Monitoring the File
/// </summary>
public void StartMonitoring()
{
// Get File Information * Setup System Watcher *
FileInfo targetFile = new FileInfo(_FileNameNPath);
_fileSystemWatcher = new FileSystemWatcher();
_fileSystemWatcher.IncludeSubdirectories = false;
_fileSystemWatcher.Path = targetFile.DirectoryName;
_fileSystemWatcher.Filter = targetFile.Name;
_fileSystemWatcher.Created += new FileSystemEventHandler(TargetFile_Created);
_fileSystemWatcher.Changed += new FileSystemEventHandler(TargetFile_Changed);
// Perform an Initial read, if the file exists
if (targetFile.Exists)
TargetFile_Created(null, null);
// Start up File System Watcher
_fileSystemWatcher.EnableRaisingEvents = true;
}
/// <summary>
/// Stop Monitoring the File
/// </summary>
/// <param name="bDispose">set to false, if you are running into trouble during a shutdown</param>
public void StopMonitoring(bool bDispose = true)
{
_fileSystemWatcher.EnableRaisingEvents = false;
if(bDispose)
_fileSystemWatcher.Dispose();
_fileSystemWatcher = null;
}
/// <summary>
/// To read a file from Beginning to End. Call this function,
/// if you want to reset the position counter and start reading again from the beginning.
/// </summary>
/// <returns>the Contents of the File</returns>
public StringBuilder ReadFromBeginningToEndOfFile()
{
_previousSeekPosition = 0;
return ReadFileContentsTillEndStartingFromPreviousSeekPosition();
}
#endregion
#region Private Helper Methods
/// <summary>
/// Handled File System Watcher's Created Callback
/// </summary>
/// <param name="source">SystemWatcher object</param>
/// <param name="e">SystemWatcher event args</param>
private void TargetFile_Created(object source, FileSystemEventArgs e)
{
// Read the File Contents
StringBuilder sb = ReadFromBeginningToEndOfFile();
//call delegate with the string
if (IncomingData != null && sb.Length > 0)
IncomingData(this, sb.ToString(), true);
}
/// <summary>
/// Handled File System Watcher's Changed Callback
/// </summary>
/// <param name="source">SystemWatcher object</param>
/// <param name="e">SystemWatcher event args</param>
private void TargetFile_Changed(object source, FileSystemEventArgs e)
{
// File size size changed to less! ~someone must have
// changed content inside of it
FileInfo targetFile = new FileInfo(_FileNameNPath);
bool bIsNew = false;
if (targetFile.Length < _previousSeekPosition)
{
_previousSeekPosition = 0;
bIsNew = true;
}
// Read the File Contents
StringBuilder sb = ReadFileContentsTillEndStartingFromPreviousSeekPosition();
//call delegate with the string
if(IncomingData != null && sb.Length > 0)
IncomingData(this, sb.ToString(), bIsNew);
}
/// <summary>
/// Helper Function to read a file from _previousSeekPosition to End.
/// </summary>
/// <returns>contents of file starting from _previousSeekPosition</returns>
private StringBuilder ReadFileContentsTillEndStartingFromPreviousSeekPosition()
{
lock (_lockingObj)
{
// Open the file
FileStream fs = new FileStream(_FileNameNPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read File Contents into a StringBuilder
StringBuilder sb = new StringBuilder();
bool bReadOrContinueReadingFile = true;
while (bReadOrContinueReadingFile)
{
// Position the file
_previousSeekPosition = (int)fs.Seek(_previousSeekPosition, SeekOrigin.Begin);
//read from current seek position to end of file
byte[] bytesRead = new byte[MAX_BYTE_TO_READ_IN_ONE_TIME];
int numBytes = fs.Read(bytesRead, 0, MAX_BYTE_TO_READ_IN_ONE_TIME);
_previousSeekPosition += numBytes;
// Append Data to the String Builder
for (int i = 0; i < numBytes; i++)
sb.Append((char)bytesRead[i]);
// If we have read up to MAX_BYTE_TO_READ_IN_ONE_TIME, then there could be more data...
bReadOrContinueReadingFile = (numBytes == MAX_BYTE_TO_READ_IN_ONE_TIME);
}
// Close File
fs.Dispose();
fs = null;
// Return SB object
return sb;
}
}
#endregion
}
}

344
Installer/Common.cs Normal file
View File

@@ -0,0 +1,344 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Yaulw.Process;
using System.IO;
using Yaulw.Tools;
using System.Diagnostics;
using Yaulw.Other;
namespace Yaulw.Installer
{
public static class Common
{
#region Setup / Spawners
/// <summary>
/// Spawn a Setup Process (Setup.exe for example)
/// </summary>
public static void PSetupSpwan(string SetupFileNameNPath, string param_s, bool bWait)
{
try
{
if (!String.IsNullOrEmpty(SetupFileNameNPath) && Tools.PathNaming.FileNameIsValid(System.IO.Path.GetFileName(SetupFileNameNPath)))
{
//string dir = Tools.PathNaming.MakeDirectoryPathValid(System.IO.Path.GetDirectoryName(SetupFileNameNPath));
//SetupFileNameNPath = dir + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileName(SetupFileNameNPath);
//if (!String.IsNullOrEmpty(param_s))
//{
// CMDline cmd = new CMDline(null, null);
// bool bIsValidParse = cmd.Parse(param_s.Split(' '), false);
// if (bIsValidParse)
// param_s = cmd.MakeValidCmdStrFromNewlyParsedCmdLine();
// else
// return; // Invalid Parameters passed in that could cause OS Command Injection
//}
PStarter.StartProcess(PStartInfo.CreateProcess(SetupFileNameNPath, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, false), bWait, false);
}
}
catch (Exception e) { throw e; }
}
/// <summary>
/// Spawn a Setup Process (Setup.exe for example) using shell execute
/// </summary>
public static void PSetupSpwanShell(string SetupFileNameNPath, string param_s, bool bWait)
{
try
{
if (!String.IsNullOrEmpty(SetupFileNameNPath) && Tools.PathNaming.FileNameIsValid(System.IO.Path.GetFileName(SetupFileNameNPath)))
{
//string dir = Tools.PathNaming.MakeDirectoryPathValid(System.IO.Path.GetDirectoryName(SetupFileNameNPath));
//SetupFileNameNPath = dir + System.IO.Path.DirectorySeparatorChar + System.IO.Path.GetFileName(SetupFileNameNPath);
//if (!String.IsNullOrEmpty(param_s))
//{
// CMDline cmd = new CMDline(null, null);
// bool bIsValidParse = cmd.Parse(param_s.Split(' '), false);
// if (bIsValidParse)
// param_s = cmd.MakeValidCmdStrFromNewlyParsedCmdLine();
// else
// return; // Invalid Parameters passed in that could cause OS Command Injection
//}
PStarter.StartProcess(PStartInfo.CreateProcess(SetupFileNameNPath, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, true), bWait, false);
}
}
catch (Exception e) { throw e; }
}
/// <summary>
/// Spawn a MSI Setup Process (*.msi)
/// </summary>
public static void PSetupMSIEXEC(string param_s)
{
try
{
string msiexec = System.Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\msiexec.exe";
if (System.IO.File.Exists(msiexec))
{
//if (!String.IsNullOrEmpty(param_s))
//{
// CMDline cmd = new CMDline(null, null);
// bool bIsValidParse = cmd.Parse(param_s.Split(' '), false);
// if (bIsValidParse)
// param_s = cmd.MakeValidCmdStrFromNewlyParsedCmdLine();
// else
// return; // Invalid Parameters passed in that could cause OS Command Injection
//}
PStarter.StartProcess(PStartInfo.CreateProcess(msiexec, param_s, "", true, System.Diagnostics.ProcessWindowStyle.Hidden, false), true, false);
}
}
catch (Exception e) { throw e; }
}
/// <summary>
/// Run a command on the commandline * Hidden *
/// </summary>
/// <param name="cmdline">cmd to run</param>
public static string RunCmdLine(string cmdline)
{
string result = PStarter.RunDosCommand(cmdline);
return result;
}
#endregion
#region Service (ServiceW Repeat with Check Existence)
/// <summary>
/// Stop a service
/// </summary>
/// <param name="ServiceName">name of service to stop</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StopService(string ServiceName)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StopService(ServiceName, true, 120);
return bSuccess;
}
/// <summary>
/// Stop a service
/// </summary>
/// <param name="ServiceName">name of service to stop</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StopService(string ServiceName, int nTimeoutBeforeKill)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StopService(ServiceName, true, nTimeoutBeforeKill);
return bSuccess;
}
/// <summary>
/// start a service
/// </summary>
/// <param name="ServiceName">name of a service to start</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StartService(string ServiceName)
{
bool bSuccess = true;
if (ServiceW.DoesServiceExist(ServiceName))
bSuccess = ServiceW.StartService(ServiceName, 120);
return bSuccess;
}
/// <summary>
/// Does Service Exist
/// </summary>
/// <param name="ServiceName">Name of service to check</param>
/// <returns>true if successful, false otherwise</returns>
public static bool ServiceExists(string ServiceName)
{
return ServiceW.DoesServiceExist(ServiceName);
}
#endregion
#region Windows Utils
/// <summary>
/// Use this to get the complete path to a .net framework utility like gacutil.exe or
/// installutil.exe.. any .net framework utility. Will fall back to look in the %temp% folder,
/// if not found, giving the opportunity to deploy the util directly with the components
/// </summary>
/// <param name="UtilFileName">the utility in .net you are looking for like gacutil.exe</param>
/// <returns>the full filenameNpath or "", if no existing file found</returns>
public static string GetNetFrameworkUtilFileNameNPathFile(string UtilFileName)
{
string windir = System.Environment.GetEnvironmentVariable("windir", EnvironmentVariableTarget.Machine);
string NetFramework1_0 = windir + "\\Microsoft.Net\\Framework\\v1.0.3705";
string NetFramework1_1 = windir + "\\Microsoft.Net\\Framework\\v1.1.4322";
string NetFramework2_0 = windir + "\\Microsoft.Net\\Framework\\v2.0.50727";
string NetFramework3_0 = windir + "\\Microsoft.Net\\Framework\\v3.0";
string NetFramework3_5 = windir + "\\Microsoft.Net\\Framework\\v3.5";
string NetFramework4_0 = windir + "\\Microsoft.Net\\Framework\\v4.0.30319";
string TempPath = PathNaming.PathEndsWithNoSlash(Path.GetTempPath()); // We use this as a Fallback, in case file doesn't exist in the framework
string[] Frameworks = new string[] { NetFramework2_0, NetFramework4_0, NetFramework1_0, NetFramework1_1, NetFramework3_0, NetFramework3_5, TempPath };
string NetUtilFileNameNPath = "";
foreach (string framework in Frameworks)
{
if (System.IO.File.Exists(framework + "\\" + UtilFileName))
{
NetUtilFileNameNPath = framework + "\\" + UtilFileName;
return NetUtilFileNameNPath;
}
};
return NetUtilFileNameNPath;
}
/// <summary>
/// Quick Helper to get the Program Files Path for the specific system
/// </summary>
/// <returns>Program Files path with a '/' at the end</returns>
public static string GetProgramFilesPathOnSystemWithEndSlash()
{
string ProgramFiles = System.Environment.GetEnvironmentVariable("ProgramFiles(x86)");
if (String.IsNullOrEmpty(ProgramFiles))
ProgramFiles = System.Environment.GetEnvironmentVariable("ProgramFiles");
return PathNaming.PathEndsWithSlash(ProgramFiles);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static string SetOwnership()
{
// in order to do any of this, sadly, we must first install the windows resource kit
//subinacl /subdirectories *.* /setowner=domainname\user
return String.Empty;
}
/// <summary>
/// To grant the specified User or group Full Control permissions to the folder and its contents
/// </summary>
/// <param name="FolderNPath">full path to folder/directory</param>
/// <param name="UserOrGroup">domainname\administrator, any windows user or group</param>
/// <returns></returns>
public static bool GrantFullPermissionToFolderForUserOrGroup(string FolderNPath, string UserOrGroup)
{
if (Directory.Exists(FolderNPath))
{
string command = String.Format("cacls \"{0}\" /t /e /g {1}:f", FolderNPath, UserOrGroup);
if (command.Contains("Invalid arguments."))
return false;
else
return true;
}
return false;
}
#endregion
#region Windows Commands
/// <summary>
/// Get The System up Time, important because we need SQL Server and Advantage up and running before
/// doing anything
/// </summary>
/// <returns></returns>
public static TimeSpan GetSystemUpTime()
{
string Result = Yaulw.Installer.Common.RunCmdLine("net statistics server");
int n = Result.IndexOf("Sessions accepted");
if (n != -1)
{
Result = Result.Substring(0, n);
n = Result.IndexOf("Statistics since ");
if (n != -1)
{
Result = Result.Substring(n + "Statistics since ".Length);
Result = Result.Replace("\n", "");
Result = Result.Replace("\r", "");
DateTime BootTime;
if (DateTime.TryParse(Result, out BootTime))
return (DateTime.Now - BootTime);
}
}
// Something went wrong with the first approach,
// let's try another...
using (var uptime = new PerformanceCounter("System", "System Up Time"))
{
uptime.NextValue(); //Call this an extra time before reading its value
return TimeSpan.FromSeconds(uptime.NextValue());
}
}
/// <summary>
/// Use this to create a quick File Shortcut on the system using ShellLink (File Only)
/// </summary>
/// <param name="TargetFileNameNPath">A valid File on the system to point to (not a url) i believe url's are created differently</param>
/// <param name="LnkFileNameNPath">a valid .lnk file name and location where to put the shortcut</param>
public static void CreateFileShortcut(string TargetFileNameNPath, string LnkFileNameNPath)
{
if (String.IsNullOrEmpty(TargetFileNameNPath) || String.IsNullOrEmpty(LnkFileNameNPath))
return;
if (!System.IO.File.Exists(TargetFileNameNPath))
return;
if (System.IO.File.Exists(LnkFileNameNPath))
System.IO.File.Delete(LnkFileNameNPath);
using (ShellLink shortcut = new ShellLink())
{
shortcut.Target = TargetFileNameNPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(TargetFileNameNPath);
shortcut.DisplayMode = ShellLink.LinkDisplayMode.edmNormal;
shortcut.Description = ""; // doesn't appear to do anything
shortcut.Save(LnkFileNameNPath);
}
}
#endregion
#region Resource Extraction
/// <summary>
/// Extract a Binary Resource from a stream and write it to a file
/// </summary>
/// <param name="resourceStream"></param>
/// <param name="FileNameNPath"></param>
/// <param name="bForceWrite"></param>
/// <returns></returns>
public static bool ExtractResourceStreamToFile(Stream resourceStream, string FileNameNPath, bool bForceWrite)
{
if (resourceStream != null && !String.IsNullOrEmpty(FileNameNPath))
{
if (bForceWrite || !System.IO.File.Exists(FileNameNPath))
{
try
{
using (resourceStream)
using (BinaryReader br = new BinaryReader(resourceStream))
using (BinaryWriter bw = new BinaryWriter(new FileStream(FileNameNPath, FileMode.Create)))
{
byte[] buffer = new byte[64 * 1024];
int numread = br.Read(buffer, 0, buffer.Length);
while (numread > 0)
{
bw.Write(buffer, 0, numread);
numread = br.Read(buffer, 0, buffer.Length);
}
bw.Flush();
}
return true;
}
catch (Exception) { /* ignore */ }
}
}
return false;
}
#endregion
}
}

249
Installer/FileIcon.cs Normal file
View File

@@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
namespace Yaulw.Installer
{
/// <summary>
/// Enables extraction of icons for any file type from
/// the Shell.
/// </summary>
/// <seealso cref="http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/ShellLink_Code_zip_ShellLink/FileIcon_cs.asp"/>
public class FileIcon
{
#region UnmanagedCode
private const int MAX_PATH = 260;
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public int dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[DllImport("shell32")]
private static extern int SHGetFileInfo(
string pszPath,
int dwFileAttributes,
ref SHFILEINFO psfi,
uint cbFileInfo,
uint uFlags);
[DllImport("user32.dll")]
private static extern int DestroyIcon(IntPtr hIcon);
private const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000;
private const int FORMAT_MESSAGE_FROM_HMODULE = 0x800;
private const int FORMAT_MESSAGE_FROM_STRING = 0x400;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x200;
private const int FORMAT_MESSAGE_MAX_WIDTH_MASK = 0xFF;
[DllImport("kernel32")]
private extern static int FormatMessage(
int dwFlags,
IntPtr lpSource,
int dwMessageId,
int dwLanguageId,
string lpBuffer,
uint nSize,
int argumentsLong);
[DllImport("kernel32")]
private extern static int GetLastError();
#endregion
#region Member Variables
private string fileName;
private string displayName;
private string typeName;
private SHGetFileInfoConstants flags;
private Icon fileIcon;
#endregion
#region Enumerations
[Flags]
public enum SHGetFileInfoConstants : int
{
SHGFI_ICON = 0x100, // get icon
SHGFI_DISPLAYNAME = 0x200, // get display name
SHGFI_TYPENAME = 0x400, // get type name
SHGFI_ATTRIBUTES = 0x800, // get attributes
SHGFI_ICONLOCATION = 0x1000, // get icon location
SHGFI_EXETYPE = 0x2000, // return exe type
SHGFI_SYSICONINDEX = 0x4000, // get system icon index
SHGFI_LINKOVERLAY = 0x8000, // put a link overlay on icon
SHGFI_SELECTED = 0x10000, // show icon in selected state
SHGFI_ATTR_SPECIFIED = 0x20000, // get only specified attributes
SHGFI_LARGEICON = 0x0, // get large icon
SHGFI_SMALLICON = 0x1, // get small icon
SHGFI_OPENICON = 0x2, // get open icon
SHGFI_SHELLICONSIZE = 0x4, // get shell size icon
//SHGFI_PIDL = 0x8, // pszPath is a pidl
SHGFI_USEFILEATTRIBUTES = 0x10, // use passed dwFileAttribute
SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays
SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay
}
#endregion
#region Implementation
/// <summary>
/// Gets/sets the flags used to extract the icon
/// </summary>
public FileIcon.SHGetFileInfoConstants Flags
{
get
{
return flags;
}
set
{
flags = value;
}
}
/// <summary>
/// Gets/sets the filename to get the icon for
/// </summary>
public string FileName
{
get
{
return fileName;
}
set
{
fileName = value;
}
}
/// <summary>
/// Gets the icon for the chosen file
/// </summary>
public Icon ShellIcon
{
get
{
return fileIcon;
}
}
/// <summary>
/// Gets the display name for the selected file
/// if the SHGFI_DISPLAYNAME flag was set.
/// </summary>
public string DisplayName
{
get
{
return displayName;
}
}
/// <summary>
/// Gets the type name for the selected file
/// if the SHGFI_TYPENAME flag was set.
/// </summary>
public string TypeName
{
get
{
return typeName;
}
}
/// <summary>
/// Gets the information for the specified
/// file name and flags.
/// </summary>
public void GetInfo()
{
fileIcon = null;
typeName = "";
displayName = "";
SHFILEINFO shfi = new SHFILEINFO();
uint shfiSize = (uint)Marshal.SizeOf(shfi.GetType());
int ret = SHGetFileInfo(
fileName, 0, ref shfi, shfiSize, (uint)(flags));
if (ret != 0)
{
if (shfi.hIcon != IntPtr.Zero)
{
fileIcon = System.Drawing.Icon.FromHandle(shfi.hIcon);
// Now owned by the GDI+ object
//DestroyIcon(shfi.hIcon);
}
typeName = shfi.szTypeName;
displayName = shfi.szDisplayName;
}
else
{
int err = GetLastError();
Console.WriteLine("Error {0}", err);
string txtS = new string('\0', 256);
int len = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
IntPtr.Zero, err, 0, txtS, 256, 0);
Console.WriteLine("Len {0} text {1}", len, txtS);
// throw exception
}
}
/// <summary>
/// Constructs a new, default instance of the FileIcon
/// class. Specify the filename and call GetInfo()
/// to retrieve an icon.
/// </summary>
public FileIcon()
{
flags = SHGetFileInfoConstants.SHGFI_ICON |
SHGetFileInfoConstants.SHGFI_DISPLAYNAME |
SHGetFileInfoConstants.SHGFI_TYPENAME |
SHGetFileInfoConstants.SHGFI_ATTRIBUTES |
SHGetFileInfoConstants.SHGFI_EXETYPE;
}
/// <summary>
/// Constructs a new instance of the FileIcon class
/// and retrieves the icon, display name and type name
/// for the specified file.
/// </summary>
/// <param name="fileName">The filename to get the icon,
/// display name and type name for</param>
public FileIcon(string fileName)
: this()
{
this.fileName = fileName;
GetInfo();
}
/// <summary>
/// Constructs a new instance of the FileIcon class
/// and retrieves the information specified in the
/// flags.
/// </summary>
/// <param name="fileName">The filename to get information
/// for</param>
/// <param name="flags">The flags to use when extracting the
/// icon and other shell information.</param>
public FileIcon(string fileName, FileIcon.SHGetFileInfoConstants flags)
{
this.fileName = fileName;
this.flags = flags;
GetInfo();
}
#endregion
}
}

953
Installer/ShellLink.cs Normal file
View File

@@ -0,0 +1,953 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Yaulw.Installer
{
#region ShellLink Object
/// <summary>
/// Summary description for ShellLink.
/// </summary>
/// <seealso cref="http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/ShellLink_Code_zip_ShellLink/ShellLink_cs.asp"/>
public class ShellLink : IDisposable
{
#region ComInterop for IShellLink
#region IPersist Interface
[ComImportAttribute()]
[GuidAttribute("0000010C-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IPersist
{
[PreserveSig]
//[helpstring("Returns the class identifier for the component object")]
void GetClassID(out Guid pClassID);
}
#endregion
#region IPersistFile Interface
[ComImportAttribute()]
[GuidAttribute("0000010B-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IPersistFile
{
// can't get this to go if I extend IPersist, so put it here:
[PreserveSig]
void GetClassID(out Guid pClassID);
//[helpstring("Checks for changes since last file write")]
void IsDirty();
//[helpstring("Opens the specified file and initializes the object from its contents")]
void Load(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
uint dwMode);
//[helpstring("Saves the object into the specified file")]
void Save(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
[MarshalAs(UnmanagedType.Bool)] bool fRemember);
//[helpstring("Notifies the object that save is completed")]
void SaveCompleted(
[MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
//[helpstring("Gets the current name of the file associated with the object")]
void GetCurFile(
[MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName);
}
#endregion
#region IShellLink Interface
[ComImportAttribute()]
[GuidAttribute("000214EE-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkA
{
//[helpstring("Retrieves the path and filename of a shell link object")]
void GetPath(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile,
int cchMaxPath,
ref _WIN32_FIND_DATAA pfd,
uint fFlags);
//[helpstring("Retrieves the list of shell link item identifiers")]
void GetIDList(out IntPtr ppidl);
//[helpstring("Sets the list of shell link item identifiers")]
void SetIDList(IntPtr pidl);
//[helpstring("Retrieves the shell link description string")]
void GetDescription(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszFile,
int cchMaxName);
//[helpstring("Sets the shell link description string")]
void SetDescription(
[MarshalAs(UnmanagedType.LPStr)] string pszName);
//[helpstring("Retrieves the name of the shell link working directory")]
void GetWorkingDirectory(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszDir,
int cchMaxPath);
//[helpstring("Sets the name of the shell link working directory")]
void SetWorkingDirectory(
[MarshalAs(UnmanagedType.LPStr)] string pszDir);
//[helpstring("Retrieves the shell link command-line arguments")]
void GetArguments(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszArgs,
int cchMaxPath);
//[helpstring("Sets the shell link command-line arguments")]
void SetArguments(
[MarshalAs(UnmanagedType.LPStr)] string pszArgs);
//[propget, helpstring("Retrieves or sets the shell link hot key")]
void GetHotkey(out short pwHotkey);
//[propput, helpstring("Retrieves or sets the shell link hot key")]
void SetHotkey(short pwHotkey);
//[propget, helpstring("Retrieves or sets the shell link show command")]
void GetShowCmd(out uint piShowCmd);
//[propput, helpstring("Retrieves or sets the shell link show command")]
void SetShowCmd(uint piShowCmd);
//[helpstring("Retrieves the location (path and index) of the shell link icon")]
void GetIconLocation(
[Out(), MarshalAs(UnmanagedType.LPStr)] StringBuilder pszIconPath,
int cchIconPath,
out int piIcon);
//[helpstring("Sets the location (path and index) of the shell link icon")]
void SetIconLocation(
[MarshalAs(UnmanagedType.LPStr)] string pszIconPath,
int iIcon);
//[helpstring("Sets the shell link relative path")]
void SetRelativePath(
[MarshalAs(UnmanagedType.LPStr)] string pszPathRel,
uint dwReserved);
//[helpstring("Resolves a shell link. The system searches for the shell link object and updates the shell link path and its list of identifiers (if necessary)")]
void Resolve(
IntPtr hWnd,
uint fFlags);
//[helpstring("Sets the shell link path and filename")]
void SetPath(
[MarshalAs(UnmanagedType.LPStr)] string pszFile);
}
[ComImportAttribute()]
[GuidAttribute("000214F9-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkW
{
//[helpstring("Retrieves the path and filename of a shell link object")]
void GetPath(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxPath,
ref _WIN32_FIND_DATAW pfd,
uint fFlags);
//[helpstring("Retrieves the list of shell link item identifiers")]
void GetIDList(out IntPtr ppidl);
//[helpstring("Sets the list of shell link item identifiers")]
void SetIDList(IntPtr pidl);
//[helpstring("Retrieves the shell link description string")]
void GetDescription(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile,
int cchMaxName);
//[helpstring("Sets the shell link description string")]
void SetDescription(
[MarshalAs(UnmanagedType.LPWStr)] string pszName);
//[helpstring("Retrieves the name of the shell link working directory")]
void GetWorkingDirectory(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir,
int cchMaxPath);
//[helpstring("Sets the name of the shell link working directory")]
void SetWorkingDirectory(
[MarshalAs(UnmanagedType.LPWStr)] string pszDir);
//[helpstring("Retrieves the shell link command-line arguments")]
void GetArguments(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs,
int cchMaxPath);
//[helpstring("Sets the shell link command-line arguments")]
void SetArguments(
[MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
//[propget, helpstring("Retrieves or sets the shell link hot key")]
void GetHotkey(out short pwHotkey);
//[propput, helpstring("Retrieves or sets the shell link hot key")]
void SetHotkey(short pwHotkey);
//[propget, helpstring("Retrieves or sets the shell link show command")]
void GetShowCmd(out uint piShowCmd);
//[propput, helpstring("Retrieves or sets the shell link show command")]
void SetShowCmd(uint piShowCmd);
//[helpstring("Retrieves the location (path and index) of the shell link icon")]
void GetIconLocation(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
int cchIconPath,
out int piIcon);
//[helpstring("Sets the location (path and index) of the shell link icon")]
void SetIconLocation(
[MarshalAs(UnmanagedType.LPWStr)] string pszIconPath,
int iIcon);
//[helpstring("Sets the shell link relative path")]
void SetRelativePath(
[MarshalAs(UnmanagedType.LPWStr)] string pszPathRel,
uint dwReserved);
//[helpstring("Resolves a shell link. The system searches for the shell link object and updates the shell link path and its list of identifiers (if necessary)")]
void Resolve(
IntPtr hWnd,
uint fFlags);
//[helpstring("Sets the shell link path and filename")]
void SetPath(
[MarshalAs(UnmanagedType.LPWStr)] string pszFile);
}
#endregion
#region ShellLinkCoClass
[GuidAttribute("00021401-0000-0000-C000-000000000046")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImportAttribute()]
private class CShellLink{}
#endregion
#region Private IShellLink enumerations
private enum EShellLinkGP : uint
{
SLGP_SHORTPATH = 1,
SLGP_UNCPRIORITY = 2
}
[Flags]
private enum EShowWindowFlags : uint
{
SW_HIDE = 0,
SW_SHOWNORMAL = 1,
SW_NORMAL = 1,
SW_SHOWMINIMIZED = 2,
SW_SHOWMAXIMIZED = 3,
SW_MAXIMIZE = 3,
SW_SHOWNOACTIVATE = 4,
SW_SHOW = 5,
SW_MINIMIZE = 6,
SW_SHOWMINNOACTIVE = 7,
SW_SHOWNA = 8,
SW_RESTORE = 9,
SW_SHOWDEFAULT = 10,
SW_MAX = 10
}
#endregion
#region IShellLink Private structs
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0,
CharSet=CharSet.Unicode)]
private struct _WIN32_FIND_DATAW
{
public uint dwFileAttributes;
public _FILETIME ftCreationTime;
public _FILETIME ftLastAccessTime;
public _FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 260)] // MAX_PATH
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0,
CharSet=CharSet.Ansi)]
private struct _WIN32_FIND_DATAA
{
public uint dwFileAttributes;
public _FILETIME ftCreationTime;
public _FILETIME ftLastAccessTime;
public _FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr , SizeConst = 260)] // MAX_PATH
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0)]
private struct _FILETIME
{
public uint dwLowDateTime;
public uint dwHighDateTime;
}
#endregion
#region UnManaged Methods
private class UnManagedMethods
{
[DllImport("Shell32", CharSet=CharSet.Auto)]
internal extern static int ExtractIconEx (
[MarshalAs(UnmanagedType.LPTStr)]
string lpszFile,
int nIconIndex,
IntPtr[] phIconLarge,
IntPtr[] phIconSmall,
int nIcons);
[DllImport("user32")]
internal static extern int DestroyIcon(IntPtr hIcon);
}
#endregion
#endregion
#region Enumerations
/// <summary>
/// Flags determining how the links with missing
/// targets are resolved.
/// </summary>
[Flags]
public enum EShellLinkResolveFlags : uint
{
/// <summary>
/// Allow any match during resolution. Has no effect
/// on ME/2000 or above, use the other flags instead.
/// </summary>
SLR_ANY_MATCH = 0x2,
/// <summary>
/// Call the Microsoft Windows Installer.
/// </summary>
SLR_INVOKE_MSI = 0x80,
/// <summary>
/// Disable distributed link tracking. By default,
/// distributed link tracking tracks removable media
/// across multiple devices based on the volume name.
/// It also uses the UNC path to track remote file
/// systems whose drive letter has changed. Setting
/// SLR_NOLINKINFO disables both types of tracking.
/// </summary>
SLR_NOLINKINFO = 0x40,
/// <summary>
/// Do not display a dialog box if the link cannot be resolved.
/// When SLR_NO_UI is set, a time-out value that specifies the
/// maximum amount of time to be spent resolving the link can
/// be specified in milliseconds. The function returns if the
/// link cannot be resolved within the time-out duration.
/// If the timeout is not set, the time-out duration will be
/// set to the default value of 3,000 milliseconds (3 seconds).
/// </summary>
SLR_NO_UI = 0x1,
/// <summary>
/// Not documented in SDK. Assume same as SLR_NO_UI but
/// intended for applications without a hWnd.
/// </summary>
SLR_NO_UI_WITH_MSG_PUMP = 0x101,
/// <summary>
/// Do not update the link information.
/// </summary>
SLR_NOUPDATE = 0x8,
/// <summary>
/// Do not execute the search heuristics.
/// </summary>
SLR_NOSEARCH = 0x10,
/// <summary>
/// Do not use distributed link tracking.
/// </summary>
SLR_NOTRACK = 0x20,
/// <summary>
/// If the link object has changed, update its path and list
/// of identifiers. If SLR_UPDATE is set, you do not need to
/// call IPersistFile::IsDirty to determine whether or not
/// the link object has changed.
/// </summary>
SLR_UPDATE = 0x4
}
public enum LinkDisplayMode : uint
{
edmNormal = EShowWindowFlags.SW_NORMAL,
edmMinimized = EShowWindowFlags.SW_SHOWMINNOACTIVE,
edmMaximized = EShowWindowFlags.SW_MAXIMIZE
}
#endregion
#region Member Variables
// Use Unicode (W) under NT, otherwise use ANSI
private IShellLinkW linkW;
private IShellLinkA linkA;
private string shortcutFile = "";
#endregion
#region Constructor
/// <summary>
/// Creates an instance of the Shell Link object.
/// </summary>
public ShellLink()
{
if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
{
linkW = (IShellLinkW)new CShellLink();
}
else
{
linkA = (IShellLinkA)new CShellLink();
}
}
/// <summary>
/// Creates an instance of a Shell Link object
/// from the specified link file
/// </summary>
/// <param name="linkFile">The Shortcut file to open</param>
public ShellLink(string linkFile) : this()
{
Open(linkFile);
}
#endregion
#region Destructor and Dispose
/// <summary>
/// Call dispose just in case it hasn't happened yet
/// </summary>
~ShellLink()
{
Dispose();
}
/// <summary>
/// Dispose the object, releasing the COM ShellLink object
/// </summary>
public void Dispose()
{
if (linkW != null )
{
Marshal.ReleaseComObject(linkW);
linkW = null;
}
if (linkA != null)
{
Marshal.ReleaseComObject(linkA);
linkA = null;
}
}
#endregion
#region Implementation
public string ShortCutFile
{
get
{
return this.shortcutFile;
}
set
{
this.shortcutFile = value;
}
}
/// <summary>
/// Gets a System.Drawing.Icon containing the icon for this
/// ShellLink object.
/// </summary>
public Icon LargeIcon
{
get
{
return getIcon(true);
}
}
public Icon SmallIcon
{
get
{
return getIcon(false);
}
}
private Icon getIcon(bool large)
{
// Get icon index and path:
int iconIndex = 0;
StringBuilder iconPath = new StringBuilder(260, 260);
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out iconIndex);
}
string iconFile = iconPath.ToString();
// If there are no details set for the icon, then we must use
// the shell to get the icon for the target:
if (iconFile.Length == 0)
{
// Use the FileIcon object to get the icon:
FileIcon.SHGetFileInfoConstants flags =
FileIcon.SHGetFileInfoConstants.SHGFI_ICON |
FileIcon.SHGetFileInfoConstants.SHGFI_ATTRIBUTES;
if (large)
{
flags = flags | FileIcon.SHGetFileInfoConstants.SHGFI_LARGEICON;
}
else
{
flags = flags | FileIcon.SHGetFileInfoConstants.SHGFI_SMALLICON;
}
FileIcon fileIcon = new FileIcon(Target, flags);
return fileIcon.ShellIcon;
}
else
{
// Use ExtractIconEx to get the icon:
IntPtr[] hIconEx = new IntPtr[1] {IntPtr.Zero};
int iconCount = 0;
if (large)
{
iconCount = UnManagedMethods.ExtractIconEx(
iconFile,
iconIndex,
hIconEx,
null,
1);
}
else
{
iconCount = UnManagedMethods.ExtractIconEx(
iconFile,
iconIndex,
null,
hIconEx,
1);
}
// If success then return as a GDI+ object
Icon icon = null;
if (hIconEx[0] != IntPtr.Zero)
{
icon = Icon.FromHandle(hIconEx[0]);
//UnManagedMethods.DestroyIcon(hIconEx[0]);
}
return icon;
}
}
/// <summary>
/// Gets the path to the file containing the icon for this shortcut.
/// </summary>
public string IconPath
{
get
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
return iconPath.ToString();
}
set
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
if (linkA == null)
{
linkW.SetIconLocation(value, iconIndex);
}
else
{
linkA.SetIconLocation(value, iconIndex);
}
}
}
/// <summary>
/// Gets the index of this icon within the icon path's resources
/// </summary>
public int IconIndex
{
get
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
return iconIndex;
}
set
{
StringBuilder iconPath = new StringBuilder(260, 260);
int iconIndex = 0;
if (linkA == null)
{
linkW.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
else
{
linkA.GetIconLocation(iconPath, iconPath.Capacity, out
iconIndex);
}
if (linkA == null)
{
linkW.SetIconLocation(iconPath.ToString(), value);
}
else
{
linkA.SetIconLocation(iconPath.ToString(), value);
}
}
}
/// <summary>
/// Gets/sets the fully qualified path to the link's target
/// </summary>
public string Target
{
get
{
StringBuilder target = new StringBuilder(260, 260);
if (linkA == null)
{
_WIN32_FIND_DATAW fd = new _WIN32_FIND_DATAW();
linkW.GetPath(target, target.Capacity, ref fd,
(uint)EShellLinkGP.SLGP_UNCPRIORITY);
}
else
{
_WIN32_FIND_DATAA fd = new _WIN32_FIND_DATAA();
linkA.GetPath(target, target.Capacity, ref fd,
(uint)EShellLinkGP.SLGP_UNCPRIORITY);
}
return target.ToString();
}
set
{
if (linkA == null)
{
linkW.SetPath(value);
}
else
{
linkA.SetPath(value);
}
}
}
/// <summary>
/// Gets/sets the Working Directory for the Link
/// </summary>
public string WorkingDirectory
{
get
{
StringBuilder path = new StringBuilder(260, 260);
if (linkA == null)
{
linkW.GetWorkingDirectory(path, path.Capacity);
}
else
{
linkA.GetWorkingDirectory(path, path.Capacity);
}
return path.ToString();
}
set
{
if (linkA == null)
{
linkW.SetWorkingDirectory(value);
}
else
{
linkA.SetWorkingDirectory(value);
}
}
}
/// <summary>
/// Gets/sets the description of the link
/// </summary>
public string Description
{
get
{
StringBuilder description = new StringBuilder(1024, 1024);
if (linkA == null)
{
linkW.GetDescription(description, description.Capacity);
}
else
{
linkA.GetDescription(description, description.Capacity);
}
return description.ToString();
}
set
{
if (linkA == null)
{
linkW.SetDescription(value);
}
else
{
linkA.SetDescription(value);
}
}
}
/// <summary>
/// Gets/sets any command line arguments associated with the link
/// </summary>
public string Arguments
{
get
{
StringBuilder arguments = new StringBuilder(260, 260);
if (linkA == null)
{
linkW.GetArguments(arguments, arguments.Capacity);
}
else
{
linkA.GetArguments(arguments, arguments.Capacity);
}
return arguments.ToString();
}
set
{
if (linkA == null)
{
linkW.SetArguments(value);
}
else
{
linkA.SetArguments(value);
}
}
}
/// <summary>
/// Gets/sets the initial display mode when the shortcut is
/// run
/// </summary>
public LinkDisplayMode DisplayMode
{
get
{
uint cmd = 0;
if (linkA == null)
{
linkW.GetShowCmd(out cmd);
}
else
{
linkA.GetShowCmd(out cmd);
}
return (LinkDisplayMode)cmd;
}
set
{
if (linkA == null)
{
linkW.SetShowCmd((uint)value);
}
else
{
linkA.SetShowCmd((uint)value);
}
}
}
/// <summary>
/// Gets/sets the HotKey to start the shortcut (if any)
/// </summary>
public Keys HotKey
{
get
{
short key = 0;
if (linkA == null)
{
linkW.GetHotkey(out key);
}
else
{
linkA.GetHotkey(out key);
}
return (Keys)key;
}
set
{
if (linkA == null)
{
linkW.SetHotkey((short)value);
}
else
{
linkA.SetHotkey((short)value);
}
}
}
/// <summary>
/// Saves the shortcut to ShortCutFile.
/// </summary>
public void Save()
{
Save(shortcutFile);
}
/// <summary>
/// Saves the shortcut to the specified file
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk)</param>
public void Save(
string linkFile
)
{
// Save the object to disk
if (linkA == null)
{
((IPersistFile)linkW).Save(linkFile, true);
shortcutFile = linkFile;
}
else
{
((IPersistFile)linkA).Save(linkFile, true);
shortcutFile = linkFile;
}
}
/// <summary>
/// Loads a shortcut from the specified file
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk) to load</param>
public void Open(
string linkFile
)
{
Open(linkFile,
IntPtr.Zero,
(EShellLinkResolveFlags.SLR_ANY_MATCH |
EShellLinkResolveFlags.SLR_NO_UI),
1);
}
/// <summary>
/// Loads a shortcut from the specified file, and allows flags controlling
/// the UI behaviour if the shortcut's target isn't found to be set.
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk) to load</param>
/// <param name="hWnd">The window handle of the application's UI, if any</param>
/// <param name="resolveFlags">Flags controlling resolution behaviour</param>
public void Open(
string linkFile,
IntPtr hWnd,
EShellLinkResolveFlags resolveFlags
)
{
Open(linkFile,
hWnd,
resolveFlags,
1);
}
/// <summary>
/// Loads a shortcut from the specified file, and allows flags controlling
/// the UI behaviour if the shortcut's target isn't found to be set. If
/// no SLR_NO_UI is specified, you can also specify a timeout.
/// </summary>
/// <param name="linkFile">The shortcut file (.lnk) to load</param>
/// <param name="hWnd">The window handle of the application's UI, if any</param>
/// <param name="resolveFlags">Flags controlling resolution behaviour</param>
/// <param name="timeOut">Timeout if SLR_NO_UI is specified, in ms.</param>
public void Open(
string linkFile,
IntPtr hWnd,
EShellLinkResolveFlags resolveFlags,
ushort timeOut
)
{
uint flags;
if ((resolveFlags & EShellLinkResolveFlags.SLR_NO_UI)
== EShellLinkResolveFlags.SLR_NO_UI)
{
flags = (uint)((int)resolveFlags | (timeOut << 16));
}
else
{
flags = (uint)resolveFlags;
}
if (linkA == null)
{
((IPersistFile)linkW).Load(linkFile, 0); //STGM_DIRECT)
linkW.Resolve(hWnd, flags);
this.shortcutFile = linkFile;
}
else
{
((IPersistFile)linkA).Load(linkFile, 0); //STGM_DIRECT)
linkA.Resolve(hWnd, flags);
this.shortcutFile = linkFile;
}
}
#endregion
}
#endregion
}

1698
Monitor/MonitorDataStore.cs Normal file

File diff suppressed because it is too large Load Diff

177
Net/Emailer.cs Normal file
View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using webmail = System.Web.Mail;
using Yaulw.Other;
// Disable System.Web.Mail is depreciated Warning
#pragma warning disable 0618
namespace Yaulw.Net
{
/// <remarks>
/// Emailer Helps you send Emails using System.Net or System.Web.Mail.
/// System.Web.Mail is depreciated, but currently is the only way to send emails via
/// SSH/SMTP on port 465.
/// </remarks>
public static class Emailer
{
#region Public Statics
/// <summary>
/// Generic Function to handle Emails
/// </summary>
/// <param name="SmtpServer">specifiy a SMTP Server to use * Required *</param>
/// <param name="SenderEmail">Email to use to send with * Required *</param>
/// <param name="SenderDisplayName">Display name for Sender * Required *</param>
/// <param name="ReceiverEmails">';' seperated list of emails to send to * Required *</param>
/// <param name="MessageSubject">Email Message Subject * Required *</param>
/// <param name="MessageText">Email Message Text * Required *</param>
/// <param name="nPort">Smtp Port to use</param>
/// <param name="ReceiverCCEmails">';' seperated list of emails to cc to</param>
/// <param name="bUseSmtpAuth">true to use SmtpAuthentication, false otherwise</param>
/// <param name="SmtpUser">Smtp Authentication Username</param>
/// <param name="SmtpPassword">Smtp Authentication Password</param>
/// <param name="RequiresSSL">true to use ssl, false otherwise</param>
/// <param name="nTimeOutInSeconds">Defaults to 100 Seconds</param>
/// <param name="exceptionFunc">If an exception occurs this delegate will get called (can be null)</param>
/// <returns>true if the Message Send Successfully, false otherwise</returns>
public static bool SendEmail(string SmtpServer, string SenderEmail, string SenderDisplayName, string ReceiverEmails, string MessageSubject, string MessageText, uint nPort, string ReceiverCCEmails, bool bUseSmtpAuth, string SmtpUser, string SmtpPassword, bool RequiresSSL, int nTimeOutInSeconds, DelegateCollection.Void_Param1_Exception_Func exceptionFunc)
{
// SSL on Port 25 is Explicit SSL, which is supported by System.Net
if (RequiresSSL && (nPort != 25))
return SendEmailUsingWebMail(SmtpServer, SenderEmail, SenderDisplayName, ReceiverEmails, MessageSubject, MessageText, nPort, ReceiverCCEmails, bUseSmtpAuth, SmtpUser, SmtpPassword, RequiresSSL, nTimeOutInSeconds, exceptionFunc);
else
return SendEmailUsingNetMail(SmtpServer, SenderEmail, SenderDisplayName, ReceiverEmails, MessageSubject, MessageText, nPort, ReceiverCCEmails, bUseSmtpAuth, SmtpUser, SmtpPassword, RequiresSSL, nTimeOutInSeconds, exceptionFunc);
}
#endregion
#region Private Statics
/// <summary>
/// Send an Email * Doesn't Support Implicit SSL (port 465) - ONLY Explicit SSL on 25
/// </summary>
/// <param name="SmtpServer">specifiy a SMTP Server to use * Required *</param>
/// <param name="SenderEmail">Email to use to send with * Required *</param>
/// <param name="SenderDisplayName">Display name for Sender * Required *</param>
/// <param name="ReceiverEmails">';' seperated list of emails to send to * Required *</param>
/// <param name="MessageSubject">Email Message Subject * Required *</param>
/// <param name="MessageText">Email Message Text * Required *</param>
/// <param name="nPort">Smtp Port to use</param>
/// <param name="ReceiverCCEmails">';' seperated list of emails to cc to</param>
/// <param name="bUseSmtpAuth">true to use SmtpAuthentication, false otherwise</param>
/// <param name="SmtpUser">Smtp Authentication Username</param>
/// <param name="SmtpPassword">Smtp Authentication Password</param>
/// <param name="RequiresSSL">true to use ssl, false otherwise</param>
/// <param name="nTimeOutInSeconds">Defaults to 100 Seconds</param>
/// <param name="exceptionFunc">If an exception occurs, this delegate gets called (can be null)</param>
/// <returns>true if the Message Send Successfully, false otherwise</returns>
private static bool SendEmailUsingNetMail(string SmtpServer, string SenderEmail, string SenderDisplayName, string ReceiverEmails, string MessageSubject, string MessageText, uint nPort, string ReceiverCCEmails, bool bUseSmtpAuth, string SmtpUser, string SmtpPassword, bool RequiresSSL, int nTimeOutInSeconds, DelegateCollection.Void_Param1_Exception_Func exceptionFunc)
{
try
{
if (String.IsNullOrEmpty(SmtpServer) || String.IsNullOrEmpty(SenderEmail) || String.IsNullOrEmpty(SenderDisplayName) || String.IsNullOrEmpty(ReceiverEmails) || String.IsNullOrEmpty(MessageSubject) || String.IsNullOrEmpty(MessageText))
return false;
SmtpClient sMail = new SmtpClient(SmtpServer);
sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
if (bUseSmtpAuth && !String.IsNullOrEmpty(SmtpUser) && !String.IsNullOrEmpty(SmtpPassword))
{
sMail.UseDefaultCredentials = false;
sMail.Credentials = new NetworkCredential(SmtpUser, SmtpPassword);
}
// Mail Message
MailMessage msg = new MailMessage();
msg.Subject = MessageSubject;
// From
msg.From = new MailAddress(SenderEmail, SenderDisplayName);
// To
foreach (string strToEmail in ReceiverEmails.Split(';'))
msg.To.Add(new MailAddress(strToEmail));
// Body
msg.Body = MessageText;
// CC
if (!String.IsNullOrEmpty(ReceiverCCEmails))
{
foreach (string strToEmail in ReceiverCCEmails.Split(';'))
msg.CC.Add(new MailAddress(strToEmail));
}
// Send it
if (nTimeOutInSeconds < 100)
nTimeOutInSeconds = 100;
sMail.Timeout = (int)TimeSpan.FromSeconds(nTimeOutInSeconds).TotalMilliseconds;
sMail.Port = ((nPort > 0) && (nPort < 65536)) ? (int)nPort : 25;
sMail.EnableSsl = RequiresSSL;
sMail.Send(msg);
return true;
}
catch (Exception e) { if (exceptionFunc != null) exceptionFunc(e); }
return false;
}
/// <summary>
/// Send an Email * Does Support SSL (port 465) via Hacks - System.Web.Mail Space however is depreciated
/// </summary>
/// <seealso cref="http://www.aspcode.net/Send-mail-from-ASPNET-using-your-gmail-account.aspx"/>
/// <param name="SmtpServer">specifiy a SMTP Server to use * Required *</param>
/// <param name="SenderEmail">Email to use to send with * Required *</param>
/// <param name="SenderDisplayName">Display name for Sender * Required *</param>
/// <param name="ReceiverEmails">';' seperated list of emails to send to * Required *</param>
/// <param name="MessageSubject">Email Message Subject * Required *</param>
/// <param name="MessageText">Email Message Text * Required *</param>
/// <param name="nPort">Smtp Port to use</param>
/// <param name="ReceiverCCEmails">';' seperated list of emails to cc to</param>
/// <param name="bUseSmtpAuth">true to use SmtpAuthentication, false otherwise</param>
/// <param name="SmtpUser">Smtp Authentication Username</param>
/// <param name="SmtpPassword">Smtp Authentication Password</param>
/// <param name="RequiresSSL">true to use ssl, false otherwise</param>
/// <param name="nTimeOutInSeconds">Defaults to 100 Seconds</param>
/// <param name="exceptionFunc">If an exception occurs, this delegate gets called (can be null)</param>
/// <returns>true if the Message Send Successfully, false otherwise</returns>
private static bool SendEmailUsingWebMail(string SmtpServer, string SenderEmail, string SenderDisplayName, string ReceiverEmails, string MessageSubject, string MessageText, uint nPort, string ReceiverCCEmails, bool bUseSmtpAuth, string SmtpUser, string SmtpPassword, bool RequiresSSL, int nTimeOutInSeconds, DelegateCollection.Void_Param1_Exception_Func exceptionFunc)
{
try
{
if (String.IsNullOrEmpty(SmtpServer) || String.IsNullOrEmpty(SenderEmail) || String.IsNullOrEmpty(SenderDisplayName) || String.IsNullOrEmpty(ReceiverEmails) || String.IsNullOrEmpty(MessageSubject) || String.IsNullOrEmpty(MessageText))
return false;
string[] Receivers = ReceiverEmails.Split(';');
foreach (string Receiver in Receivers)
{
webmail.MailMessage Mail = new System.Web.Mail.MailMessage();
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"] = SmtpServer;
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 2;
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"] = nPort.ToString();
if (RequiresSSL)
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/smtpusessl"] = "true";
if (bUseSmtpAuth)
{
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] = 1;
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"] = SmtpUser;
Mail.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"] = SmtpPassword;
}
// Send Message
Mail.To = Receiver;
Mail.From = SenderEmail;
Mail.Subject = MessageSubject;
Mail.Body = MessageText;
webmail.SmtpMail.SmtpServer = SmtpServer;
webmail.SmtpMail.Send(Mail);
}
return true;
}
catch (Exception e) { if (exceptionFunc != null) exceptionFunc(e); }
return false;
}
#endregion
}
}

832
Net/IPHostHelper.cs Normal file
View File

@@ -0,0 +1,832 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Yaulw.Win32;
using System.Management;
using System.IO;
namespace Yaulw.Net
{
/// <summary>
/// Helper for common IP / Host Machine
/// </summary>
public static class IPHostHelper
{
#region Public consts
/// <summary>
/// This automation URL used to work, now it no longer works :(
/// Caller must set this before calling ExternalIP() Functions
/// </summary>
public static string WHAT_IS_MY_IP_AUTOMATION_URL = "http://automation.whatismyip.com/n09230945.asp";
#endregion
#region IPv4 Checkers
/// <summary>
/// Checks to see that the passed in ip is a valid Local IP
/// address that is of version 4 and not a broadcast/loopback/None
/// </summary>
/// <param name="ip"></param>
/// <param name="bAllowLoopback">true to allow Loopback address as valid Local IP</param>
/// <returns></returns>
/// <remarks>
/// IPAddress.IPv6Any = "::";
/// IPAddress.Any = "0.0.0.0"
/// IPAddress.Broadcast = "255.255.255.255"
/// IPAddress.None = "255.255.255.255"
/// IPAddress.Loopback = "127.0.0.1"
/// </remarks>
public static bool IsValidIPv4Address(IPAddress ip, bool bAllowLoopback)
{
if (ip != null)
{
if (ip.AddressFamily != AddressFamily.InterNetwork)
return false;
if (ip.AddressFamily.ToString().Contains(IPAddress.IPv6Any.ToString()))
return false;
if (ip == IPAddress.Any)
return false;
if (ip == IPAddress.Broadcast)
return false;
if (ip == IPAddress.None)
return false;
// Loopback technically is a valid Local IP that can be used to communicate
// to ourselves (on the same machine)
if (ip == IPAddress.Loopback)
return bAllowLoopback;
// This must be a valid local IPv4
return true;
}
return false;
}
/// <summary>
/// Checks to see if the passed in ip is in a valid Private subnet (i.e. not public)
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
/// <remarks>
/// Private subnets as defined in <seealso cref="http://tools.ietf.org/html/rfc1918"/>
/// Loopback address 127.0.0.1/8 <seealso cref="http://tools.ietf.org/html/rfc3330"/>
/// Zeroconf/bonjour self assigned addresses 169.254.0.0/16 <seealso cref="http://tools.ietf.org/html/rfc3927"/>
/// </remarks>
public static bool IsIPv4AddressInPrivateSubnet(IPAddress ip)
{
if (!IsValidIPv4Address(ip, true))
return false;
String[] netAddrs = { "192.168.0.0", "10.0.0.0", "172.16.0.0", "127.0.0.1", "169.254.0.0" };
String[] netMasks = { "255.255.0.0", "255.0.0.0", "255.240.0.0", "255.0.0.0", "255.255.0.0" };
UInt32 myIP = BitConverter.ToUInt32(ip.GetAddressBytes(), 0);
for (int i = 0; i < netMasks.Length; i++)
{
IPAddress netAddr = IPAddress.Parse(netAddrs[i]);
UInt32 netIP = BitConverter.ToUInt32(netAddr.GetAddressBytes(), 0);
IPAddress maskAddr = IPAddress.Parse(netMasks[i]);
UInt32 maskIP = BitConverter.ToUInt32(maskAddr.GetAddressBytes(), 0);
if ((myIP & maskIP) == (netIP & maskIP))
return true;
}
return false;
}
/// <summary>
/// Compares two IP Addresses, if the Left One is different from the right one, assigns
/// the right one to the LeftOrRight (simple) and returns true. Otherwise assigns left to it and returns false.
/// </summary>
public static bool AreIPAddressesDifferent(IPAddress left, IPAddress right, out IPAddress LeftOrRight)
{
LeftOrRight = left;
if (left != null && right != null)
{
if (String.Compare(left.ToString(), right.ToString(), true) != 0)
{
LeftOrRight = right;
return true;
}
}
else if (left == null && right != null)
{
LeftOrRight = right;
return true;
}
return false;
}
#endregion
#region Connectivity
/// <summary>
/// Method to check if the Local Computer has a valid Network Connection
/// </summary>
/// <returns></returns>
public static bool HasConnection()
{
//instance of our ConnectionStatusEnum
Definitions.ConnectionStatusEnum state = 0;
//call the API
bool bIsConnected = Wininet.InternetGetConnectedState(ref state, 0);
if (!bIsConnected)
return false;
//check the status, if in offline mode then return false
if (((int)Definitions.ConnectionStatusEnum.INTERNET_CONNECTION_OFFLINE & (int)state) != 0)
return false;
return true;
}
/// <summary>
/// Method to check to see if local Computer has a valid Network connection
/// and can open the specified ip and port
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public static bool HasConnectivity(IPAddress ip, uint port)
{
if(HasConnection() && IsValidIPv4Address(ip, true) && port > 0)
return IsPortOpen(ip, (int) port);
return false;
}
/// <summary>
/// Method to check to see if local Computer has a valid Network connection
/// and can open the specified host and port
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
/// <param name="nTimeout"></param>
/// <returns></returns>
public static bool HasConnectivity(string host, uint port, int nTimeout)
{
if (HasConnection() && port > 0)
{
IPAddress ip = GetIpForHost(host);
if(ip != IPAddress.None && IsValidIPv4Address(ip, false))
return IsPortOpen(ip, (int) port, nTimeout);
}
return false;
}
/// <summary>
/// Retrieves the Servername from a DataBaseConnectionString, if possible,
/// then gets the ip for the server name and tries to open up the port specified
/// </summary>
/// <param name="DataBaseConnectionString">pass in either a DataSource or ConnectionString</param>
/// <param name="port"></param>
/// <returns></returns>
public static bool HasConnectivity(string DataBaseConnectionString, uint port)
{
if (HasConnection() && !String.IsNullOrEmpty(DataBaseConnectionString))
{
// Allow the SharedConnectionDataSource to be a ConnectionString also via calling GetDataSource()
DataBaseConnectionString = GetDataSource(DataBaseConnectionString);
// Retrieve the IP for the Data Source and test the ip and set it in the API
string host = GetServerNameFromADataSource(DataBaseConnectionString);
IPAddress ip = GetIpForHost(host);
if (ip != IPAddress.None)
{
if (IsPortOpen(ip, (int) port))
return true;
}
}
return false;
}
#endregion
#region Core IPHostHelper Functionallity
/// <summary>
/// Converts all incl. Loopback, if contained, valid IP addresses into a String array of IPs
/// </summary>
/// <returns></returns>
public static string[] ConvertIPArrayToStringArray(IPAddress[] IPs)
{
List<string> ips = new List<string>();
if (IPs != null && IPs.Length > 0)
{
foreach (IPAddress ip in IPs)
{
if (IsValidIPv4Address(ip, true))
ips.Add(ip.ToString());
}
}
return ips.ToArray();
}
/// <summary>
/// Get all valid IPv4 Local IP addresses besides the loopback address
/// </summary>
/// <returns></returns>
public static IPAddress[] GetAllLocalIPAddresses()
{
// Get host name
String HostName = Dns.GetHostName();
IPHostEntry iphostentry = Dns.GetHostEntry(HostName);
// Enumerate IP addresses
List<IPAddress> IPs = new List<IPAddress>();
foreach (IPAddress ipaddress in iphostentry.AddressList)
{
if (IsValidIPv4Address(ipaddress, false))
IPs.Add(ipaddress);
}
// Return them as a string[] of IPs
return IPs.ToArray();
}
/// <summary>
/// Get First Found Local IP Address (or IPAddress.None, if none found)
/// </summary>
/// <returns>get the first Local IP Address found</returns>
public static IPAddress GetFirstLocalIPAddress()
{
IPAddress[] IPs = GetAllLocalIPAddresses();
if (IPs.Length > 0)
return IPs[0];
else
return IPAddress.None;
}
/// <summary>
/// Get Nth Found Local IP Address (or first one found, if n > IPs Found)
/// (or IPAddress.None, if none found)
/// </summary>
/// <returns>get the Nth Local IP Address found</returns>
public static IPAddress GetNthLocalIPAddress(int n)
{
IPAddress[] IPs = GetAllLocalIPAddresses();
if (n >= 0 && IPs.Length < n)
return IPs[n];
else if (IPs.Length > 0)
return IPs[0];
else
return IPAddress.None;
}
/// <summary>
/// Check to see if the host passed in is Local
/// </summary>
/// <param name="host">can be ip or host name</param>
/// <returns>true, if host or ip is local, false otherwise</returns>
/// <exception cref="ArgumentException">When host is empty</exception>
public static bool IsHostOrIPLocal(string host)
{
if (!String.IsNullOrEmpty(host))
{
IPAddress ip = null;
if (IPAddress.TryParse(host, out ip))
{
IPAddress[] localIPs = GetAllLocalIPAddresses();
foreach(IPAddress localip in localIPs)
{
if (localip == ip)
return true;
}
return false;
}
else
{
return (String.Compare(host.Trim(), Dns.GetHostName(), true) == 0);
}
}
throw new ArgumentException("Invalid host");
}
/// <summary>
/// Method for resolving a Host (DNS Resolve)
/// </summary>
/// <param name="host">the host</param>
/// <param name="bMustBeInPrivateIPRange">Set to true, if the host must be in the Private IP Range</param>
/// <returns>true, if host can be resolved to an IP Address, false otherwise</returns>
public static bool CanResolveHost(string host, bool bMustBeInPrivateIPRange)
{
if(!String.IsNullOrEmpty(host))
{
IPAddress ip = GetIpForHost(host);
if (bMustBeInPrivateIPRange)
return IsIPv4AddressInPrivateSubnet(ip);
return (ip != IPAddress.None);
}
return false;
}
/// <summary>
/// Method for retrieving the IP address for a Host (DNS Resolve)
/// </summary>
/// <param name="host">the host we need the ip address for</param>
/// <returns>an IPAddress if found, otherwise IPAddress.None</returns>
public static IPAddress GetIpForHost(string host)
{
//variable to hold our error message (if something fails)
string errMessage = string.Empty;
//IPAddress instance for holding the returned host
IPAddress address = IPAddress.None;
//wrap the attempt in a try..catch to capture
//any exceptions that may occur
try
{
// if it's already an ip address being passed in,
// we are done
if (!IPAddress.TryParse(host, out address))
{
//get the host IP from the name provided
address = Dns.GetHostEntry(host).AddressList[0];
// We must be called for the local host, that
// could explain why it is not a valid IP
if (!IsValidIPv4Address(address, false))
address = GetFirstLocalIPAddress();
}
else
{
address = IPAddress.Parse(host);
}
}
catch (Exception) { /* ignore */ }
if (address == null)
return IPAddress.None;
else
return address;
}
/// <summary>
/// Ping a host
/// </summary>
/// <param name="host">url/host/ip</param>
/// <param name="nTimeout">timeout value in miliseconds</param>
/// <param name="nTrys">number of times to ping</param>
/// <returns>the number of successful pings</returns>
public static int PingHost(string host, int nTimeout, int nTrys)
{
//string to hold our return messge
//string returnMessage = string.Empty;
// Check to see if the host passed in is an IP Address
// otherwise, just resolve the host
IPAddress address = null;
if(!IPAddress.TryParse(host, out address))
address = GetIpForHost(host);
// Error occured resolving host
if (!IsValidIPv4Address(address, false))
return 0;
//set the ping options, TTL 128
PingOptions pingOptions = new PingOptions(128, true);
//create a new ping instance
Ping ping = new Ping();
//32 byte buffer (create empty)
byte[] buffer = new byte[32];
//first make sure we actually have an internet connection
int nPingSuccess = 0;
if (HasConnection())
{
//here we will ping the host nTrys times
for (int i = 0; i < nTrys; i++)
{
try
{
PingReply pingReply = ping.Send(address, nTimeout, buffer, pingOptions);
if (!(pingReply == null))
{
switch (pingReply.Status)
{
case IPStatus.Success:
nPingSuccess++;
break;
case IPStatus.TimedOut:
default:
break;
}
}
}
catch (Exception) { /* ignore and continue iterating */ }
}
}
return nPingSuccess;
}
#endregion
#region Port Open
/// <summary>
/// Check to see if a port is open for the specified ip
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
/// <returns></returns>
public static bool IsPortOpen(IPAddress ip, int port)
{
bool bCanConnect = false;
if (IsValidIPv4Address(ip, true) && port > 0)
{
try
{
TcpClient tcP = new System.Net.Sockets.TcpClient();
tcP.Connect(ip, port);
bCanConnect = true;
tcP.Close();
}
catch (Exception) { /* ignore */ }
}
return bCanConnect;
}
/// <summary>
/// Check to see if a port is open for the specified ip
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
/// <returns></returns>
public static bool IsPortOpen(IPAddress ip, int port, int nTimeout)
{
bool bCanConnect = false;
if (IsValidIPv4Address(ip, true) && port > 0)
{
try
{
TcpClient tcP = new System.Net.Sockets.TcpClient();
if (nTimeout > 0)
tcP.ReceiveTimeout = nTimeout;
tcP.Connect(ip, port);
bCanConnect = true;
tcP.Close();
}
catch (Exception) { /* ignore */ }
}
return bCanConnect;
}
#endregion
#region Get External IP
/// <summary>
/// Get the External IP
/// </summary>
/// <param name="pTimeOutMiliSeconds">Timeout in MiliSeconds</param>
/// <returns>a valid external IPAddress or IPAddress.None, if error occured</returns>
public static IPAddress GetExternalIP(int pTimeOutMiliSeconds)
{
IPAddress extIP = IPAddress.None;
try
{
using (WebClient wc = new WebClient())
{
wc.Headers.Add("user-agent", WCHelper.USER_AGENT_GENERIC);
UTF8Encoding utf8 = new UTF8Encoding();
string ipaddr = null;
bool done = false;
wc.DownloadDataCompleted += new
DownloadDataCompletedEventHandler((object sender,
DownloadDataCompletedEventArgs e) =>
{
ipaddr = utf8.GetString(e.Result);
done = true;
});
wc.DownloadDataAsync(new Uri(WHAT_IS_MY_IP_AUTOMATION_URL));
System.DateTime startTime = System.DateTime.Now;
while (!done)
{
System.TimeSpan sp = System.DateTime.Now - startTime;
// We should get a response in less than timeout.
// If not, we cancel all and return the internal IP Address
if (sp.TotalMilliseconds > pTimeOutMiliSeconds)
{
done = true;
wc.CancelAsync();
}
}
if (IPAddress.TryParse(ipaddr, out extIP))
return extIP;
}
}
catch { /* ignore */ }
return IPAddress.None;
}
/// <summary>
/// Get the External IP
/// </summary>
/// <returns>a valid external IPAddress or IPAddress.None, if error occured</returns>
public static IPAddress GetExternalIP()
{
string ipaddr = WCHelper.ScreenScrapeFromURL(WHAT_IS_MY_IP_AUTOMATION_URL);
IPAddress extIP = IPAddress.None;
if (IPAddress.TryParse(ipaddr, out extIP))
return extIP;
return IPAddress.None;
}
/// <summary>
/// Call this to retrieve the external IP Address (also makes sure we can connect
/// to WhatIsMyIp site)
/// </summary>
/// <param name="bForceMultipleChecks">
/// Forces 4 checks at 2.5/5.0/7.5/10 seconds timeout values
/// otherwise makes one request defaulting to 5.0
/// </param>
/// <returns>valid external IP Address or null if not found</returns>
public static IPAddress GetExternalIP(bool bForceMultipleChecks)
{
if (HasConnection())
{
IPAddress ipExtIP = null;
if (bForceMultipleChecks)
{
// Check with an timout of 2.5/5.0/7.5/10 seconds
for (int n = 2500; n <= 10000; n = n + 2500)
{
ipExtIP = GetExternalIP(n);
if(ipExtIP != IPAddress.None)
return ipExtIP;
}
}
else
{
// Check with whatever is the default timeout
ipExtIP = Yaulw.Net.IPHostHelper.GetExternalIP(5000);
return ipExtIP;
}
}
return IPAddress.None;
}
#endregion
#region UNC and Path Related Windows Network Helpers
/// <summary>
/// Allows us to use either pass in a ConnectionString or a DataSource * Added flexibility *
/// will return the DataSource part of the connection string, if exists, otherwise the connection string
/// </summary>
/// <param name="DataBaseConnectionString">pass in either a DataSource or ConnectionString</param>
/// <returns></returns>
public static string GetDataSource(string DataBaseConnectionString)
{
if (IsDataBaseConnectionString(DataBaseConnectionString))
{
String[] tokens = DataBaseConnectionString.Split(';');
foreach (string Pair in tokens)
{
string[] KeyValuePair = Pair.Split('=');
try
{
string left = KeyValuePair[0];
string right = KeyValuePair[1];
string FoundValue = "";
if (String.Compare(KeyValuePair[0].ToUpper().Trim(), "DATA SOURCE", true) == 0)
{
if (!String.IsNullOrEmpty(right))
{
FoundValue = right.Trim();
return FoundValue;
}
}
}
catch (Exception) { /* ignore and continue iteration */ }
}
}
// Migth still be a data source just not from a Connection string
// so just return the value trimmed
if (!String.IsNullOrEmpty(DataBaseConnectionString))
return DataBaseConnectionString.Trim();
else
return String.Empty;
}
/// <summary>
/// Quick Check to see if a connection string is valid * must have DataSource Key and
/// a Value * in order to be considered a valid Connection String
/// </summary>
/// <param name="ConnectionString"></param>
/// <returns></returns>
public static bool IsDataBaseConnectionString(string ConnectionString)
{
if (!String.IsNullOrEmpty(ConnectionString) &&
ConnectionString.ToUpper().Contains("DATA SOURCE") &&
ConnectionString.Contains("="))
{
String[] tokens = ConnectionString.Split(';');
foreach (string Pair in tokens)
{
string[] KeyValuePair = Pair.Split('=');
try
{
string left = KeyValuePair[0];
string right = KeyValuePair[1];
if (String.Compare(KeyValuePair[0].ToUpper().Trim(), "DATA SOURCE", true) == 0)
return !String.IsNullOrEmpty(right);
}
catch (Exception) { /* ignore and continue iteration */ }
}
return true;
}
return false;
}
/// <summary>
/// Returns the Server Name from a Database DataSource Connection String
/// </summary>
/// <param name="DataSource">
/// [DriveLetter]:\{SomeFileNameNPath}
/// \\{Server]\{SomeFileNameNPath}
/// \\{Server]:[Port]\{SomeFileNameNPath}
/// [Server]\Instance
/// [Server]
/// </param>
/// <remarks>Server string returned can be a name or an IP address</remarks>
/// <returns>Server Host Name or IP</returns>
public static string GetServerNameFromADataSource(string DataSource)
{
if (!String.IsNullOrEmpty(DataSource))
{
// Always strip out port in the DataSource *before doing anything*
// only do this for non-local paths
if (DataSource.Contains(":") && DataSource[1] != ':')
{
int nLoc = DataSource.IndexOf(":");
if (nLoc != -1)
DataSource = DataSource.Substring(0, nLoc);
}
// Let's begin ...
string Server = String.Empty;
// Local Medisoft
bool bIsLocalFilePath = DataSource.Contains(@":\");
if (bIsLocalFilePath)
{
string PathInCaseMapped = ResolveToUNCIfNeeded(DataSource);
// It's a local or a UNC path
if (!PathInCaseMapped.StartsWith(@"\\"))
{
// If Local file that the host is this computer
return Dns.GetHostName();
}
else
{
// else it's the other host * so follow UNC logic *
// Stripe out first 2 chars
Server = PathInCaseMapped.Substring(2);
// Stripe out the rest
int nLoc = Server.IndexOf(@"\");
if (nLoc != -1)
Server = Server.Substring(0, nLoc);
}
}
// Remote Medisoft
bool bIsNetworkFilePath = DataSource.StartsWith(@"\\");
if (bIsNetworkFilePath)
{
// Stripe out first 2 chars
Server = DataSource.Substring(2);
// Stripe out the rest
int nLoc = Server.IndexOf(@"\");
if (nLoc != -1)
Server = Server.Substring(0, nLoc);
}
// It's Lytec! :)
bool bIsSQLServerInstance = !bIsLocalFilePath && !bIsNetworkFilePath;
if (bIsSQLServerInstance)
{
// Stripe out Instance, if it exists
int nLoc = DataSource.IndexOf(@"\");
if (nLoc != -1)
Server = DataSource.Substring(0, nLoc);
else
Server = DataSource;
}
return Server;
}
return String.Empty;
}
/// <summary>
/// Determines if the passed in string is a connection string or a data Source
/// and tries to make the best of things to retrieve the host/server name
/// </summary>
/// <param name="ConnectionString"></param>
/// <returns></returns>
public static string GetServerNameFromAConnectionString(string ConnectionString)
{
if (IsDataBaseConnectionString(ConnectionString))
{
string DataSource = GetDataSource(ConnectionString);
return GetServerNameFromADataSource(DataSource);
}
else
{
// Pretentd that it is just a DataSource
return GetServerNameFromADataSource(ConnectionString);
}
}
/// <summary>Resolves the given path to a UNC path, or local drive path.</summary>
/// <param name="pPath"></param>
/// <returns>\\server\share\[path] OR [driveletter]:\[path]</returns>
public static string ResolveToUNCIfNeeded(string pPath)
{
if (String.IsNullOrEmpty(pPath))
return String.Empty;
ManagementObject mo = new ManagementObject();
// Already UNC, we are done here
if (pPath.StartsWith(@"\\")) { return pPath; }
// Get just the drive letter for WMI call
string driveletter = GetDriveLetter(pPath);
mo.Path = new ManagementPath(string.Format("Win32_LogicalDisk='{0}'", driveletter));
// Get the data we need
uint DriveType = System.Convert.ToUInt32(mo["DriveType"]);
string NetworkRoot = System.Convert.ToString(mo["ProviderName"]);
mo = null;
// Return the root UNC path if network drive, otherwise return the root path to the local drive
if (DriveType == 4)
{
return NetworkRoot + pPath.Substring(2);
}
else
{
return driveletter + pPath.Substring(2);
}
}
/// <summary>Checks if the given path is on a network drive.</summary>
/// <param name="pPath"></param>
/// <returns></returns>
public static bool isNetworkDrive(string pPath)
{
ManagementObject mo = new ManagementObject();
if (pPath.StartsWith(@"\\")) { return true; }
// Get just the drive letter for WMI call
string driveletter = GetDriveLetter(pPath);
mo.Path = new ManagementPath(string.Format("Win32_LogicalDisk='{0}'", driveletter));
// Get the data we need
uint DriveType = System.Convert.ToUInt32(mo["DriveType"]);
mo = null;
return DriveType == 4;
}
#endregion
#region Private Helpers
/// <summary>Given a path will extract just the drive letter with volume separator.</summary>
/// <param name="pPath"></param>
/// <returns>C:</returns>
private static string GetDriveLetter(string pPath)
{
if (pPath.StartsWith(@"\\")) { throw new ArgumentException("A UNC path was passed to GetDriveLetter"); }
return Directory.GetDirectoryRoot(pPath).Replace(Path.DirectorySeparatorChar.ToString(), "");
}
#endregion
}
}

14
Net/RouterHelper.cs Normal file
View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Net
{
public static class RouterHelper
{
}
}

73
Net/WCHelper.cs Normal file
View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace Yaulw.Net
{
/// <summary>
/// WebClient Helper class to get commen stuff done
/// </summary>
public static class WCHelper
{
public const string USER_AGENT_IE8 = "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB7.4; InfoPath.2; SV1; .Net CLR 3.3.69573; .NET CLR 1.0.3705; WOW64; rv:12.0; en-US) Gecko/20100101 Firefox/12.0";
public const string USER_AGENT_GENERIC = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0";
/// <summary>
/// Download the specified URL file to the local path
/// </summary>
/// <param name="URLFileNameNPath"></param>
/// <param name="LocalFileNameNPath"></param>
/// <param name="bOverwriteExisting"></param>
/// <returns></returns>
public static bool DownloadFileFromURL(string URLFileNameNPath, string LocalFileNameNPath, bool bOverwriteExisting)
{
if(!String.IsNullOrEmpty(URLFileNameNPath) && !String.IsNullOrEmpty(LocalFileNameNPath))
{
try
{
using (WebClient fileReader = new WebClient())
{
//string filename = URLFileNameNPath.Substring(URLFileNameNPath.LastIndexOf("/"), URLFileNameNPath.Length);
if (!System.IO.File.Exists(LocalFileNameNPath) || bOverwriteExisting)
fileReader.DownloadFile(URLFileNameNPath, LocalFileNameNPath);
}
return true;
}
catch (Exception) { /* ignore */ }
}
return false;
}
/// <summary>
/// ScreenScrape the Text from the URL
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
public static string ScreenScrapeFromURL(string URL)
{
if (!String.IsNullOrEmpty(URL))
{
try
{
using (WebClient fileReader = new WebClient())
{
fileReader.Headers.Add("user-agent", USER_AGENT_GENERIC);
using (Stream data = fileReader.OpenRead(URL))
using (StreamReader sr = new StreamReader(data))
{
string str = sr.ReadToEnd();
return str;
}
}
}
catch (Exception) { /* ignore */ }
}
return "";
}
}
}

292
Net/WSCaller.cs Normal file
View File

@@ -0,0 +1,292 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Refl = System.Reflection;
using System.Net;
using System.Web.Services.Description;
using System.CodeDom;
using System.CodeDom.Compiler;
using Yaulw.Other;
namespace Yaulw.Net
{
/// <remarks>
/// Class to Make Soap Web Services Calls Dynamically (Works only for Microsoft-based Web Services it seems)
/// </remarks>
public class WSCaller
{
#region Private Members
private string _ServiceName = ""; // example: "WebService"
private string _Url = ""; // example: "http://webservice.com/WebService/WebService.asmx"
private Refl.Assembly _webServiceAssembly = null;
// available services
private List<string> _services = new List<string>();
// available types
private Dictionary<string, Type> _availableTypes = new Dictionary<string, Type>();
private bool _InvokeMethodErrorWasThrown = false;
#endregion
#region Construction
/// <summary>
/// Creates the service invoker using the specified web service.
/// </summary>
/// <param name="ServiceName">Name of Web Service</param>
/// <param name="ServiceUrl">Url of Web Service</param>
public WSCaller(string ServiceName, string ServiceUrl)
{
if (!String.IsNullOrEmpty(ServiceName) && !String.IsNullOrEmpty(ServiceUrl))
{
// Store Service Specifics
_ServiceName = ServiceName;
_Url = ServiceUrl;
// Try Creating the WS Assembly
CreateAssemblyFromWebServiceDescription();
}
else
throw new ArgumentNullException("Service Name or Service Url can not be Null or Empty");
}
#endregion
#region Public Methods
/// <summary>
/// Check to see if the Web Service Is Available
/// </summary>
public bool WebServiceAvailable
{
get
{
CreateAssemblyFromWebServiceDescription();
return (_webServiceAssembly != null);
}
}
/// <summary>
/// Make the Soap Method Call
/// </summary>
/// <param name="MethodName">Method Name to call</param>
/// <param name="parameters">parameters to use on call</param>
/// <param name="bCallSuccess">true if called successfully, false otherwise</param>
/// <returns>the return value of the Method</returns>
public T MakeSoapMethodCall<T>(string MethodName, object[] parameters, out bool bCallSuccess, DelegateCollection.Void_Param1_Exception_Func exception)
{
bCallSuccess = false;
try
{
List<String> Methods = EnumerateServiceMethods(_ServiceName);
if (Methods.Count == 0)
return default(T);
// Try making a CheckActive Call
T result = InvokeMethod<T>(_ServiceName, MethodName, parameters);
bCallSuccess = true;
return result;
}
catch (Exception e) { _InvokeMethodErrorWasThrown = true; if (exception != null) exception(e); }
return default(T);
}
#endregion
#region Private Helpers
/// <summary>
/// create an assembly from the web service description (WSDL)
/// </summary>
private void CreateAssemblyFromWebServiceDescription()
{
// Error Occured upon invoke, try rebuilding the WS
if (_InvokeMethodErrorWasThrown && _webServiceAssembly != null)
_webServiceAssembly = null;
// In Order to properly build/rebuild the WS must be available
if (_webServiceAssembly == null)
{
_webServiceAssembly = BuildAssemblyFromWSDL(new Uri(_Url));
if (_webServiceAssembly != null)
{
// Reset
_InvokeMethodErrorWasThrown = false;
// see what service types are available
Type[] types = _webServiceAssembly.GetExportedTypes();
// and save them
foreach (Type type in types)
{
_services.Add(type.FullName);
_availableTypes.Add(type.FullName, type);
}
}
}
}
/// <summary>
/// Gets a list of all methods available for the specified service.
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
private List<string> EnumerateServiceMethods(string serviceName)
{
List<string> methods = new List<string>();
if (!_availableTypes.ContainsKey(serviceName))
{
throw new Exception("Service Not Available");
}
else
{
Type type = _availableTypes[serviceName];
// only find methods of this object type (the one we generated)
// we don't want inherited members (this type inherited from SoapHttpClientProtocol)
foreach (Refl.MethodInfo minfo in type.GetMethods(Refl.BindingFlags.Instance | Refl.BindingFlags.Public | Refl.BindingFlags.DeclaredOnly))
methods.Add(minfo.Name);
return methods;
}
}
/// <summary>
/// Invokes the specified method of the named service.
/// </summary>
/// <typeparam name="T">The expected return type.</typeparam>
/// <param name="serviceName">The name of the service to use.</param>
/// <param name="methodName">The name of the method to call.</param>
/// <param name="args">The arguments to the method.</param>
/// <returns>The return value from the web service method.</returns>
private T InvokeMethod<T>(string serviceName, string methodName, params object[] args)
{
// create an instance of the specified service
// and invoke the method
object obj = null;
Type type = null;
try
{
obj = _webServiceAssembly.CreateInstance(serviceName);
type = obj.GetType();
}
catch (Exception e)
{
throw new Exception(e.Message + " " + "Creation of webServiceAssembly Failed");
}
// Find the Service Point for the Web Service! ~Fix 100 - HTTP 417 Error
ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(_Url));
if (servicePoint.Expect100Continue == true)
servicePoint.Expect100Continue = false;
return (T)type.InvokeMember(methodName, Refl.BindingFlags.InvokeMethod, null, obj, args);
}
/// <summary>
/// Builds an assembly from a web service description.
/// The assembly can be used to execute the web service methods.
/// </summary>
/// <param name="webServiceUri">Location of WSDL (only pass in the main asmx url without the ?wdsl).</param>
/// <returns>A web service assembly.</returns>
private Refl.Assembly BuildAssemblyFromWSDL(Uri webServiceUri)
{
try
{
if (String.IsNullOrEmpty(webServiceUri.ToString()))
throw new Exception("Web Service Not Found");
ServiceDescriptionImporter descriptionImporter = BuildServiceDescriptionImporter((webServiceUri.ToString() + "?wsdl"));
return CompileAssembly(descriptionImporter);
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// Builds the web service description importer, which allows us to generate a proxy class based on the
/// content of the WSDL described by the XmlTextReader.
/// </summary>
/// <param name="wsdlUrl">The http location of the WSDL</param>
/// <returns>A ServiceDescriptionImporter that can be used to create a proxy class.</returns>
private ServiceDescriptionImporter BuildServiceDescriptionImporter(string wsdlUrl)
{
try
{
WebClient http = new WebClient();
ServiceDescription serviceDescription = ServiceDescription.Read(http.OpenRead(wsdlUrl));
// build an importer, that assumes the SOAP protocol, client binding, and generates properties
ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();
descriptionImporter.ProtocolName = "Soap";
descriptionImporter.AddServiceDescription(serviceDescription, null, null);
descriptionImporter.Style = ServiceDescriptionImportStyle.Client;
descriptionImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
return descriptionImporter;
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// Compiles an assembly from the proxy class provided by the ServiceDescriptionImporter.
/// </summary>
/// <param name="descriptionImporter"></param>
/// <returns>An assembly that can be used to execute the web service methods.</returns>
private Refl.Assembly CompileAssembly(ServiceDescriptionImporter descriptionImporter)
{
try
{
// a namespace and compile unit are needed by importer
CodeNamespace codeNamespace = new CodeNamespace();
CodeCompileUnit codeUnit = new CodeCompileUnit();
codeUnit.Namespaces.Add(codeNamespace);
ServiceDescriptionImportWarnings importWarnings = descriptionImporter.Import(codeNamespace, codeUnit);
if (importWarnings == 0) // no warnings
{
// create a c# compiler
CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp");
// include the assembly references needed to compile
string[] references = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters parameters = new CompilerParameters(references);
// compile into assembly
CompilerResults results = compiler.CompileAssemblyFromDom(parameters, codeUnit);
foreach (CompilerError oops in results.Errors)
{
// trap these errors and make them available to exception object
throw new Exception("Compilation Error Creating Assembly");
}
// all done....
return results.CompiledAssembly;
}
else
{
// warnings issued from importers, something wrong with WSDL
throw new Exception("Invalid WSDL");
}
}
catch (Exception)
{
return null;
}
}
#endregion
}
}

423
Other/CMDLine.cs Normal file
View File

@@ -0,0 +1,423 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using Yaulw.Tools;
namespace Yaulw.Other
{
/// <remarks>
/// CommandLine Arguments Parser for an Application
/// <example>
/// <code>
/// internal CMDline cmdline = new CMDline(typeof(App.CommandLine_Option), typeof(App.CommandLine_Flag));
///
/// public enum CommandLine_Flag
/// {
/// START,
/// STOP,
/// SHOW,
/// }
///
/// public enum CommandLine_Option
/// {
/// ADD_SOMETHING,
/// REMOVE_SOMETHING,
/// }
///
/// cmdline.Parse(e.Args);
///
/// if (cmdline.HasParams)
/// {
/// if (App.cmdline.ShowHelp || !App.cmdline.ParamsValid)
/// {
/// ShowCommandLineHelp();
/// return;
/// }
///
/// string AddSomething = cmdline.GetOptionValue<string>(CommandLine_Option.ADD_SOMETHING, ""); //</string>
/// }
/// </code>
/// </example>
/// </remarks>
public class CMDline
{
#region private Variables
// Flag or Option Specifiers CONSTS
private const String FLAG_OR_OPTION_SPECIFIER = "-/";
private const String HELP_FLAG_SPECIFIER = "?";
// Private Parsing Enums
private Type _CMDLineOptions = null;
private Type _CMDLineFlags = null;
// Private Parsing Data Structures
private Stack<String> _stringStack = new Stack<String>();
private StringDictionary _stringDictionary = new StringDictionary();
// Keep track of the last parsed args as an array
private string[] _lastparsedArgs = null;
#endregion
#region Construction
/// <summary>
/// The Command Line Class needs to know what Options and Flags to Parse for
/// </summary>
/// <param name="CMDLineOptions">Pass an Enum used to determine CommandLine Options</param>
/// <param name="CMDLineFlags">Pass an Enum used to determine CommandLine Flags</param>
public CMDline(Type Enum_CMDLineOptions, Type Enum_CMDLineFlags)
{
if (Enum_CMDLineOptions.IsEnum && Enum_CMDLineFlags.IsEnum)
{
_CMDLineOptions = Enum_CMDLineOptions;
_CMDLineFlags = Enum_CMDLineFlags;
}
else
throw new ArgumentException("Both CMDLineOptions and CMDLineFlags must be Enums");
}
#endregion
#region Public Properties
/// <summary>
/// True if User Passed in any Parameters
/// </summary>
public bool HasParams { get { return (_stringDictionary.Count >= 1); } }
/// <summary>
/// True if User requested Command-Line Help
/// </summary>
public bool ShowHelp { get { return GetFlagOrOptionValueBool(HELP_FLAG_SPECIFIER); } }
/// <summary>
/// True if all Parameters parsed are valid, False otherwise
/// </summary>
public bool ParamsValid
{
get
{
if (!HasParams)
return true;
string[] OptionNames = Enum.GetNames(_CMDLineOptions);
string[] FlagNames = Enum.GetNames(_CMDLineFlags);
// Get All Flags and Options
List<String> AllFlagsAndOptions = new List<String>();
foreach (string Option in OptionNames)
AllFlagsAndOptions.Add(Option.ToLower());
foreach (string Flag in FlagNames)
AllFlagsAndOptions.Add(Flag.ToLower());
// Verify the Parameters
bool InvalidParamFound = false;
foreach (string key in _stringDictionary.Keys)
{
InvalidParamFound = (key != HELP_FLAG_SPECIFIER) && !AllFlagsAndOptions.Contains(key);
if (InvalidParamFound)
break;
}
return !InvalidParamFound;
}
}
#endregion
#region Public Methods
/// <summary>
/// Main Entry Function to Retrieve an Option Value
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="option">option to retrieve (From CMDLineOptions Enum)</param>
/// <param name="DefaultValue">Default value to use if nothing was retrieved * Error occured *</param>
/// <returns>value or default value, if not found</returns>
public T GetOptionValue<T>(Enum option, T DefaultValue)
{
T RetVal = DefaultValue;
string StringVal = GetFlagOrOptionValueStr(option.ToString());
try
{
if (ObjTool.IsNotNullAndNotEmpty(StringVal))
{
RetVal = ObjTool.ConvertStringToObj<T>(StringVal);
}
}
catch (Exception) { /* ignore */ }
return RetVal;
}
/// <summary>
/// Main Entry Function to Retrieve a Flag Value
/// </summary>
/// <param name="flag">flag enum to retrieve (From CMDLineFlags Enum)</param>
/// <returns>Bool Value found or false if not found</returns>
public bool GetFlagValue(Enum flag)
{
return GetFlagOrOptionValueBool(flag.ToString());
}
/// <summary>
/// Returns the Last Parsed Arguments as a string
/// </summary>
/// <returns>returns last parsed args or String.Empty if none</returns>
public string ParsedArgs()
{
if (_lastparsedArgs != null && _lastparsedArgs.Length > 0)
{
StringBuilder sb = new StringBuilder();
foreach (string s in _lastparsedArgs)
{
sb.Append(s);
sb.Append(" ");
}
sb.Remove(sb.Length - 1, 1); // remove trailing " "
return sb.ToString();
}
return string.Empty;
}
#endregion
#region Private Helper Functions
/// <summary>
/// Main Function used to Retrieve a String Value
/// </summary>
/// <param name="FlagOrOption">Flag or Option to get Value for</param>
/// <returns>Value or Empty if not found</returns>
private string GetFlagOrOptionValueStr(string FlagOrOption)
{
// If there is a FLAG_OR_OPTION_CHARS, stripe it
if (IsFlagOrOption(FlagOrOption))
FlagOrOption = GetFlagOrOption(FlagOrOption);
FlagOrOption = FlagOrOption.ToLower();
if (_stringDictionary.ContainsKey(FlagOrOption))
return _stringDictionary[FlagOrOption];
return String.Empty;
}
/// <summary>
/// Main Function used to Retrieve a Bool Value
/// </summary>
/// <param name="FlagOrOption">Flag or Option to get Value for</param>
/// <returns>True or False if not found</returns>
private bool GetFlagOrOptionValueBool(string FlagOrOption)
{
try
{
string Value = GetFlagOrOptionValueStr(FlagOrOption);
if (!String.IsNullOrEmpty(Value))
{
bool bValue = bool.Parse(Value);
return bValue;
}
}
catch (Exception) { /*Ignore*/ }
return false;
}
#endregion
#region Parsing Methods
/// <returns>true if the param is a flag or option</returns>
private bool IsFlagOrOption(string arg)
{
return (FLAG_OR_OPTION_SPECIFIER.Contains(arg[0].ToString()));
}
/// <returns>the Value of a Param</returns>
private string GetFlagOrOption(string arg)
{
return arg.Substring(1);
}
/// <summary>
/// Main Entry Function used to Parse CommandLine parameters
/// </summary>
/// <param name="args">command line arguments</param>
/// <returns>true if any parsing occured, false otherwise</returns>
public bool Parse(string[] args)
{
return Parse(args, true);
}
/// <summary>
/// Main Entry Function used to Parse CommandLine parameters
/// </summary>
/// <param name="args">command line arguments</param>
/// <param name="bAlwaysParseOptionsAsTrue">Allows you to not parse Options as True, if in case the option is blank it will just be considered a blank option/flag</param>
/// <returns>true if any parsing occured, false otherwise</returns>
public bool Parse(string[] args, bool bAlwaysParseOptionsAsTrue)
{
if (args == null || args.Length <= 0)
return false;
_stringDictionary.Clear();
_stringStack.Clear();
_lastparsedArgs = args;
foreach (string arg in args)
{
if (!String.IsNullOrEmpty(arg))
{
if (IsFlagOrOption(arg))
{
_stringStack.Push(GetFlagOrOption(arg).ToLower());
if (bAlwaysParseOptionsAsTrue)
_stringDictionary[GetFlagOrOption(arg).ToLower()] = "TRUE";
}
else
{
// must have a flag or option on the stack,
// if it does we use it
if (_stringStack.Count >= 1)
{
_stringDictionary[_stringStack.Pop()] = Parse_ArgCleanup(arg);
}
}
}
}
_stringStack.Clear();
return true;
}
/// <summary>
/// Used only when cmd is constructed with (null, null),
/// and the cmd.Parse function is called. will iterate thru the internal
/// dictionary and stack and make sure that the command string / line items
/// are valid
/// </summary>
/// <returns></returns>
public string MakeValidCmdStrFromNewlyParsedCmdLine()
{
StringBuilder sb = new StringBuilder();
foreach (string key in _stringDictionary.Keys)
{
sb.Append(FLAG_OR_OPTION_SPECIFIER[0]);
sb.Append(MakeValidCmdStr(key));
sb.Append("=");
sb.Append(_stringDictionary[key]);
sb.Append("");
}
foreach (string flag in _stringStack)
{
sb.Append(FLAG_OR_OPTION_SPECIFIER[0]);
sb.Append(MakeValidCmdStr(flag));
sb.Append("");
}
// remove trailing space
sb = sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
/// <summary>
/// It appears that the Command-Line can foul us up sometimes when passing
/// certain arguments. This function deals with these special cases.
/// </summary>
/// <param name="arg">arg to check/poss.clean up</param>
/// <returns>cleaned up arg, if needed</returns>
private string Parse_ArgCleanup(string arg)
{
if (!String.IsNullOrEmpty(arg) &&
(arg.Length > 2) &&
(arg[arg.Length - 1] == '"')) // when passing a \ at the end of the command-line with a "
{
arg = arg.Remove(arg.Length - 1);
arg += "\\";
}
return arg;
}
#endregion
#region Static Generate CmdLine Method
/// <summary>
/// Generates a CommandLine Parameter String from the Options/Flags Given
/// </summary>
/// <param name="Options">StringDictionary that contains all the Options, to use</param>
/// <param name="Flags">List that contains all the Flags to use</param>
/// <returns>a string that can be passed via the commandLine</returns>
public static string GenerateCmdLine(StringDictionary Options, List<String> Flags)
{
string CmdLine = String.Empty;
// Iterate Options, and add them
if (Options != null && Options.Count > 0)
{
foreach (string Key in Options.Keys)
{
string cmdKey = MakeValidCmdStr(Key);
string cmdValue = Options[Key];
CmdLine = CmdLine + FLAG_OR_OPTION_SPECIFIER[0] + cmdKey + " " + "\"" + cmdValue + "\"" + " ";
}
}
// Iterate Flags, and add them
if (Flags != null && Flags.Count > 0)
{
foreach (string Flag in Flags)
{
string cmdFlag = MakeValidCmdStr(Flag);
CmdLine = CmdLine + FLAG_OR_OPTION_SPECIFIER[0] + cmdFlag + " ";
}
}
// Return the generated Commmand Line
return CmdLine;
}
/// <summary>
/// Ensures Integrity with the Generated CMDLine string that Keys don't
/// contain Illegal Characters
/// </summary>
/// <param name="Key">a Key to make sure it is valid</param>
/// <returns>a valid Key</returns>
private static string MakeValidCmdStr(string Key)
{
if (!String.IsNullOrEmpty(Key))
{
//":\\ _!@#$%^&()-+{}[],.;`~";
Key = Key.Replace(" ", "_");
Key = Key.Replace(":", "_");
Key = Key.Replace("\\", "_");
Key = Key.Replace("/", "_");
Key = Key.Replace("!", "_");
Key = Key.Replace("@", "_");
Key = Key.Replace("#", "_");
Key = Key.Replace("$", "_");
Key = Key.Replace("%", "_");
Key = Key.Replace("^", "_");
Key = Key.Replace("&", "_");
Key = Key.Replace("(", "_");
Key = Key.Replace(")", "_");
Key = Key.Replace("-", "_");
Key = Key.Replace("+", "_");
Key = Key.Replace("{", "_");
Key = Key.Replace("}", "_");
Key = Key.Replace("[", "_");
Key = Key.Replace("]", "_");
Key = Key.Replace(",", "_");
Key = Key.Replace(".", "_");
Key = Key.Replace(";", "_");
Key = Key.Replace("'", "_");
Key = Key.Replace("~", "_");
return Key;
}
return String.Empty;
}
#endregion
}
}

102
Other/CMDcommands.cs Normal file
View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Other
{
/// <remarks>
/// Commonly used Batch/CMD command Line Command
/// </remarks>
public static class CMDcommands
{
#region CMDCommands
/// <summary>
/// map a credential to a network path
/// </summary>
/// <param name="path">network path</param>
/// <param name="user">user</param>
/// <param name="pwd">password</param>
/// <returns>Command-Line Command</returns>
static public string net_use(string path, string user, string pwd)
{
return ("net use " + path + " /User:" + user + " " + pwd);
}
/// <summary>
/// map a credential and drive letter to a network path
/// </summary>
/// <param name="path">network path</param>
/// <param name="driveletter">drive letter to map</param>
/// <param name="user">user</param>
/// <param name="pwd">password</param>
/// <param name="path"></param>
/// <returns>Command-Line Command</returns>
static public string net_use_persist(string path, string driveletter, string user, string pwd)
{
return ("net use " + driveletter + ": " + path + " /User:" + user + " " + pwd + " PERSISTENT:YES");
}
/// <summary>
/// Delete a Network Credential from a network path
/// </summary>
/// <param name="path">network path</param>
/// <returns>Command-Line Command</returns>
static public string net_delete(string path)
{
return ("net use /delete " + path);
}
/// <summary>
/// Delete a Drive Letter and Network Credential from a network path
/// </summary>
/// <param name="driveletter"></param>
/// <returns>Command-Line Command</returns>
static public string net_delete_persist(string driveletter)
{
return ("net use /delete " + driveletter + ":");
}
#endregion
#region PSTools
/// <remarks>
/// Commands for System Internals PSExec Tools
/// </remarks>
public static class PSTools
{
/// <summary>
/// PSExec is a System Internals Remote Execution CommandLine tool.
/// Use this to execute a .bat/.cmd file on the other computer
/// </summary>
/// <param name="computer">Name of computer</param>
/// <param name="file">.bat or .cmd file to execute</param>
/// <param name="user">user</param>
/// <param name="pwd">password</param>
/// <param name="interactive">true to allow remote process to interact with desktop</param>
/// <returns>Command-Line Command</returns>
static public string ps_exec(string computer, string file, string user, string pwd, bool interactive)
{
string Show = "";
if (interactive)
Show = "-i ";
if (file.ToLower().Contains(".bat") || file.ToLower().Contains(".cmd"))
{
// copy .bat or .cmd file over
return (@"psexec.exe \\" + computer + " -u " + user + " -p " + pwd + " -c -f -e -d " + Show + "/accepteula " + '\"' + file + '\"');
}
else
{
// doesn't copy over, executes command from location, don't wait for process to terminate
return (@"psexec.exe \\" + computer + " -u " + user + " -p " + pwd + " -d -e " + Show + "/accepteula " + '\"' + file + '\"');
}
}
}
#endregion
}
}

83
Other/CMDexecute.cs Normal file
View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Yaulw.File;
namespace Yaulw.Other
{
/// <remarks>
/// Usefull for quickly generating a .bat file and executing it (without a command window)
/// </remarks>
public static class CMDexecute
{
#region Public Static Methods
/// <summary>
/// Executes the passed in command on the command line * No Command Window Created *
/// </summary>
/// <param name="command">a command-line command</param>
/// <param name="bWait">true to wait till process ends, false otherwise</param>
/// <param name="bUseRunAs">If true, will set "RunAs" For the Process, to Run as Administrator</param>
public static void cmd(string command, bool bWait = true, bool bRunAs = false)
{
FileWriter fileW = new FileWriter(String.Empty, "bat");
fileW.DeleteFile();
fileW.WriteLineUTF8(command);
execBatFile(fileW.FileNameNPath, bWait, bRunAs);
fileW.DeleteFile();
}
/// <summary>
/// Executes the passed in commands on the command line * No Command Window Created *
/// </summary>
/// <param name="commands">command-line commands</param>
/// <param name="bWait">true to wait till process ends, false otherwise</param>
/// <param name="bUseRunAs">If true, will set "RunAs" For the Process, to Run as Administrator</param>
public static void cmd(string[] commands, bool bWait = true, bool bRunAs = false)
{
FileWriter fileW = new FileWriter(String.Empty, "bat");
fileW.DeleteFile();
foreach (string command in commands)
fileW.WriteLineUTF8(command);
execBatFile(fileW.FileNameNPath, bWait, bRunAs);
fileW.DeleteFile();
}
#endregion
#region Private Static Helpers
/// <summary>
/// Executes the Batch file via CMD.exe, by starting the CMD.exe Process with no Window
/// </summary>
/// <param name="FileNameNPath">File (.bat) scrip to execute</param>
/// <param name="bWait">true to wait till process ends, false otherwise</param>
private static void execBatFile(string FileNameNPath, bool bWait = true, bool bUseRunAs = false)
{
if (!String.IsNullOrEmpty(FileNameNPath) && System.IO.File.Exists(FileNameNPath))
{
//The "/C" Tells Windows to Run The Command then Terminate
string strCmdLine = "/C " + '\"' + FileNameNPath + '\"';
string WindowsSystem32Folder = System.Environment.GetFolderPath(Environment.SpecialFolder.System);
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo((WindowsSystem32Folder + "\\" + "CMD.exe"), strCmdLine);
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.WorkingDirectory = Path.GetDirectoryName(FileNameNPath);
if (bUseRunAs)
startInfo.Verb = "runas";
// Start the Cmd.exe Process
System.Diagnostics.Process p1;
p1 = System.Diagnostics.Process.Start(startInfo);
if(bWait)
p1.WaitForExit();
}
}
#endregion
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Yaulw.Other
{
/// <remarks>
/// Common Delegates * Useful for Dispatching *
/// </remarks>
public static class DelegateCollection
{
// 0 Params Functions
public delegate void Void_Func();
public delegate bool Bool_Func();
public delegate int Int_Func();
public delegate object Obj_Func();
public delegate DateTime DateTime_Func();
// Void Ret - 1 Params Functions
public delegate void Void_Param1_String_Func(string str1);
public delegate void Void_Param1_Int_Func(int int1);
public delegate void Void_Param1_DateTime_Func(DateTime dt1);
public delegate void Void_Param1_Exception_Func(Exception ex1);
// Bool Ret - 1 Params Functions
public delegate bool Bool_Param1_String_Func(string str1);
public delegate bool Bool_Param1_Window_Func(Window window);
// String Ret - 1 Params Functions
public delegate string String_Param1_Bool_Func(bool bool1);
public delegate string String_Param1_String_Func(string str1);
}
}

43
Other/Installer.cs Normal file
View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Yaulw.Process;
namespace Yaulw.Other
{
public static class Installer
{
/// <summary>
/// Run a command on the commandline * Hidden *
/// </summary>
/// <param name="cmdline">cmd to run</param>
public static string RunCmdLine(string cmdline)
{
string result = PStarter.RunDosCommand(cmdline);
return result;
}
/// <summary>
/// To grant the specified User or group Full Control permissions to the folder and its contents
/// </summary>
/// <param name="FolderNPath">full path to folder/directory</param>
/// <param name="UserOrGroup">domainname\administrator, any windows user or group</param>
/// <returns></returns>
public static bool GrantFullPermissionToFolderForUserOrGroup(string FolderNPath, string UserOrGroup)
{
if (Directory.Exists(FolderNPath))
{
string command = String.Format("cacls \"{0}\" /t /e /g {1}:f", FolderNPath, UserOrGroup);
string strResult = RunCmdLine(command);
if (strResult.Contains("Invalid arguments."))
return false;
else
return true;
}
return false;
}
}
}

116
Other/OSInfo.cs Normal file
View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Yaulw.Win32;
namespace Yaulw.Other
{
#region OSInfo Enums
/// <summary>
/// Windows OS Types
/// </summary>
public enum OStype
{
WIN_2000 = 4,
WIN_2003 = 5,
WIN_VISTA = 6,
WIN_7 = 7,
WIN_8 = 8,
WIN_UNKNOWN = -1,
}
#endregion
/// <remarks>
/// This class provides OS Specific and Version information to the caller
/// </remarks>
public static class OSInfo
{
#region Public Properties
/// <summary>
/// Get OSType and Version Information
/// </summary>
public static int Major { get; private set; }
public static int Minor { get; private set; }
public static OStype OS { get; private set; }
/// <summary>
/// Set Supported Version for an Application
/// </summary>
public static OStype MinVersionSupported { get; set; }
public static OStype MaxVersionSupported { get; set; }
/// <summary>
/// Is this OS Version Supported * Min/Max Should be set by Application *
/// </summary>
public static bool IsSupportedOS
{
get
{
if (MinVersionSupported != OStype.WIN_UNKNOWN && MaxVersionSupported != OStype.WIN_UNKNOWN)
return ((int) OS >= (int)MinVersionSupported) && ((int) OS <= (int)MaxVersionSupported);
else
return true;
}
}
/// <summary>
/// Is Vista/Win7's Aero Enabled
/// </summary>
public static bool IsAero
{
get
{
if (((int)OS >= (int)OStype.WIN_VISTA) || ((int)OS <= (int)OStype.WIN_7))
{
bool IsAero = false;
if (uxDwm.DwmIsCompositionEnabled(ref IsAero) < 0)
return false;
else
return IsAero;
}
return false;
}
}
/// <summary>
/// Is WindowsXP/2003 Composition Enabled
/// </summary>
public static bool IsXPComposition
{
get
{
if ((int)OS == (int)OStype.WIN_2003)
return uxDwm.IsAppThemed();
return false;
}
}
#endregion
#region Construction
/// <summary>
/// Constructor
/// </summary>
static OSInfo()
{
// Get the OS Version
Major = System.Environment.OSVersion.Version.Major;
Minor = System.Environment.OSVersion.Version.Minor;
// Parse the OS Version
try { OSInfo.OS = (OStype)Enum.Parse(typeof(OStype), Major.ToString()); }
catch (Exception) { OSInfo.OS = OStype.WIN_UNKNOWN; }
// Set Min/Max to Unknown
MinVersionSupported = OStype.WIN_UNKNOWN;
MaxVersionSupported = OStype.WIN_UNKNOWN;
}
#endregion
}
}

57
Other/StackWalker.cs Normal file
View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
namespace Yaulw.Other
{
/// <remarks>
/// Use the StackWalker to Find out what Method/Type Called you.
/// This is useful for logging functions to know what method/type called the Logging Method.
/// </remarksy>
public static class StackWalker
{
/// <summary>
/// Hard-Coded in Stack Frame count depending on how this Class is getting called,
/// and how many frames we have to go up / down (use nPlusMinus)
/// </summary>
public const int DEFAULT_STACK_FRAME_COUNT = 3;
/// <summary>
/// Use this to get the MethodName from the CallStack.
/// This allows the calling method to know which method called it
/// </summary>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <returns>Returns the MethodName as specified by the CallStack</returns>
public static string GetMethodNameFromStack(int nPlusMinus = 0)
{
StackTrace stackTrace = new StackTrace();
StackFrame stackFrame;
MethodBase stackFrameMethod;
stackFrame = stackTrace.GetFrame(DEFAULT_STACK_FRAME_COUNT + nPlusMinus);
stackFrameMethod = stackFrame.GetMethod();
return stackFrameMethod.Name;
}
/// <summary>
/// Use this to get the Type from the CallStack.
/// This allows the calling method to know which type called it.
/// </summary>
/// <param name="nPlusMinus">Use this to add/substract from the base stack level you want to retrieve</param>
/// <returns>Returns the Type as specified by the CallStack</returns>
public static Type GetTypeFromStack(int nPlusMinus = 0)
{
StackTrace stackTrace = new StackTrace();
StackFrame stackFrame;
MethodBase stackFrameMethod;
stackFrame = stackTrace.GetFrame(DEFAULT_STACK_FRAME_COUNT + nPlusMinus);
stackFrameMethod = stackFrame.GetMethod();
return stackFrameMethod.ReflectedType;
}
}
}

255
Other/StateM.cs Normal file
View File

@@ -0,0 +1,255 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using Yaulw.Tools;
namespace Yaulw.Other
{
/// <remarks>
/// Easy StateManager to store and retrieve various Application States using an Enum
/// <example>
/// <code>
/// internal enum State
/// {
/// App_Started_bool,
/// App_ErrorsOccured_bool,
/// SpecialMode_CommandLine_Mode_bool,
/// }
///
/// internal static StateM AppState = new StateM(typeof(State));
/// </code>
/// </example>
/// </remarks>
public class StateM : IDisposable
{
#region Private Members
// Private Parsing Enums
private Type _StateKeys = null;
private StringDictionary _sdCurrentState = new StringDictionary(); // For State String Convertible Types
private Dictionary<String, Object> _sdCurrentStateObj = new Dictionary<string, object>(); // For State Object Types
private bool _disposed = false;
private object _lock = new object();
#endregion
#region Construction
/// <summary>
/// The StateM needs to know what Keys to Get/Set
/// </summary>
/// <param name="Enum_StateKeys">Pass an Enum used to determine StateKeys</param>
public StateM(Type Enum_StateKeys)
{
if (Enum_StateKeys.IsEnum)
{
_StateKeys = Enum_StateKeys;
}
else
throw new ArgumentException("StateKeys must be an Enum");
}
/// <summary>
/// Finalizer
/// </summary>
~StateM()
{
Dispose(true);
}
#endregion
#region Public Properties
/// <summary>
/// True if User Has passed in State Values
/// </summary>
public bool HasStates { get { return (_sdCurrentState.Count >= 1 || _sdCurrentStateObj.Count >= 1); } }
#endregion
#region Public Methods
/// <summary>
/// Main Entry Function to Retrieve an State Value
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="stateKey">State Value you want to retrieve</param>
/// <param name="DefaultValue">Default value to use if nothing was retrieved * Error occured *</param>
/// <returns>value or default value, if not found</returns>
public T GetStateValue<T>(Enum stateKey, T DefaultValue)
{
lock (_lock)
{
T RetVal = DefaultValue;
if (ObjTool.IsOfTypeConvertibleToString<T>(DefaultValue))
{
string Value = String.Empty;
if (GetStateValue(stateKey, out Value) && !String.IsNullOrEmpty(Value))
RetVal = ObjTool.ConvertStringToObj<T>(Value);
}
else
{
object o = null;
if (GetStateValue(stateKey, out o) && (o != null))
RetVal = (T)o;
}
return RetVal;
}
}
/// <summary>
/// Main Entry Function to Set a State Value
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="stateKey">State Value you want to set</param>
/// <param name="Value">Value you want to set</param>
/// <returns>true if successful, false otherwise</returns>
public bool SetStateValue<T>(Enum stateKey, T Value)
{
lock (_lock)
{
bool bSuccess = false;
if (ObjTool.IsOfTypeConvertibleToString<T>(Value))
{
string strValue = ObjTool.ConvertObjToString<T>(Value);
bSuccess = SetStateValue(stateKey, strValue);
}
else
{
bSuccess = SetStateValue(stateKey, (object)Value);
}
return bSuccess;
}
}
#endregion
#region Private Helper Methods
/// <summary>
/// Private GetStateValue Getter Function
/// </summary>
/// <param name="stateKey">pass in the State to look for</param>
/// <param name="Value">Returns the value or String.Empty, if none</param>
/// <returns>true if the State Value Exists, false otherwise</returns>
private bool GetStateValue(Enum stateKey, out string Value)
{
lock (_lock)
{
Value = String.Empty;
if (_sdCurrentState.ContainsKey(stateKey.ToString()))
{
Value = _sdCurrentState[stateKey.ToString()];
return true;
}
return false;
}
}
/// <summary>
/// Private GetStateValue Getter Function
/// </summary>
/// <param name="stateKey">pass in the State to look for</param>
/// <param name="o">Returns the object or null, if noone</param>
/// <returns>true if the State Value Exists, false otherwise</returns>
private bool GetStateValue(Enum stateKey, out object o)
{
lock (_lock)
{
o = null;
if (_sdCurrentStateObj.ContainsKey(stateKey.ToString()))
{
o = _sdCurrentStateObj[stateKey.ToString()];
return true;
}
return false;
}
}
/// <summary>
/// Private SetStateValue Setter Function
/// </summary>
/// <param name="stateKey">pass in the State to Set</param>
/// <param name="Value">The Value to Set</param>
/// <returns>true if the State Value was set, false otherwise</returns>
private bool SetStateValue(Enum stateKey, string Value)
{
lock (_lock)
{
try
{
_sdCurrentState[stateKey.ToString()] = Value;
return true;
}
catch (Exception) { /* ignore */ }
return false;
}
}
/// <summary>
/// Private SetStateValue Setter Function
/// </summary>
/// <param name="stateKey">pass in the State to Set</param>
/// <param name="o">The Object to Set</param>
/// <returns>true if the State Value was set, false otherwise</returns>
private bool SetStateValue(Enum stateKey, object o)
{
lock (_lock)
{
try
{
_sdCurrentStateObj[stateKey.ToString()] = o;
return true;
}
catch (Exception) { /* ignore */ }
return false;
}
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose the State Object
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose the State Object
/// </summary>
/// <param name="disposing">true, if called from within</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
foreach (object o in _sdCurrentStateObj)
{
if (o is IDisposable)
((IDisposable)o).Dispose();
}
_sdCurrentStateObj.Clear();
}
// Indicate that the instance has been disposed.
_sdCurrentState = null;
_sdCurrentStateObj = null;
_disposed = true;
}
}
#endregion
}
}

78
Other/TraceM.cs Normal file
View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Threading = System.Threading;
using System.Diagnostics;
namespace Yaulw.Other
{
/// <remarks>
/// Wrapper Class arround Tracing, designed to measure performance.
/// Use this class to measure performance arround your calls.
/// <example>
/// TraceM.TraceBegin()
/// ... Some Code....
/// ... Some More Code...
/// TraceM.TraceEnd("Custom Message");
/// </example>
/// </remarks>
public static class TraceM
{
#region Private Statics
private static Dictionary<uint, Stack<DateTime>> s_ThreadTraceBeginTSMap = new Dictionary<uint, Stack<DateTime>>();
public static bool EnableTracing { get; set; }
#endregion
#region Construction
/// <summary>
/// Construction * Tracing by default is disabled *
/// </summary>
static TraceM()
{
EnableTracing = false;
}
#endregion
#region Public Statics
/// <summary>
/// Call this to Start the Performance Trace
/// </summary>
public static void TraceBegin()
{
if (EnableTracing)
{
uint curThreadId = (uint)Threading.Thread.CurrentThread.ManagedThreadId;
if (!s_ThreadTraceBeginTSMap.ContainsKey(curThreadId))
s_ThreadTraceBeginTSMap[curThreadId] = new Stack<DateTime>();
s_ThreadTraceBeginTSMap[curThreadId].Push(DateTime.Now);
}
}
/// <summary>
/// Us this to End the Performance Trace
/// </summary>
/// <param name="CustomMessage">Custom Message you want displayed in the Trace Window</param>
public static void TraceEnd(string CustomMessage = "")
{
if (EnableTracing)
{
uint curThreadId = (uint)Threading.Thread.CurrentThread.ManagedThreadId;
if (s_ThreadTraceBeginTSMap.ContainsKey(curThreadId))
{
DateTime orgTime = s_ThreadTraceBeginTSMap[curThreadId].Pop();
TimeSpan ts = DateTime.Now - orgTime;
Trace.WriteLine((CustomMessage + " (Time Taken in ms " + ts.TotalMilliseconds.ToString() + ")"));
}
}
}
#endregion
}
}

550
Other/Versioning.cs Normal file
View File

@@ -0,0 +1,550 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace Yaulw.Other
{
/// <summary>
/// Interface of Versioning, to check if the passed in version is supported by the Versioning Object
/// </summary>
public interface IVersionSupported
{
bool IsSupported(string Version);
bool IsSupported(Versioning Version);
bool IsSupported(Version Version);
}
/// <remarks>
/// Allows us to easily wrap Versioning Functionallity,
/// into Objects. Similar to Assembly.Version Class, however,
/// it allows the * character. This character specifies all and
/// allows for wildchar versioning schemes useful for certain
/// scenarios via IVersionSupported.
/// ---------------------------------------------------
/// [Major version].[Minor version].[Build number].[Revision number]
/// ---------------------------------------------------
/// Major version can be any valid uint as well as *
/// Minor version can be any valid uint as well as *
/// Build number can be any valid uint as well as *
/// Revision number can be any valid uint as well as *
/// </remarks>
public class Versioning : ICloneable, IComparable, IVersionSupported
{
#region Public consts
/// <summary>
/// Int value indicating a * (wildcard) character
/// </summary>
public const int STAR_ALL = -1;
#endregion
#region Private Members
private int _MajorVersion = STAR_ALL;
private int _MinorVersion = STAR_ALL;
private int _BuildNumber = STAR_ALL;
private int _RevisionNumber = STAR_ALL;
#endregion
#region Construction
/// <summary>
/// Use this to initialize the class with a version string, can not contain multiple versions seperated by ";"
/// </summary>
/// <param name="strVersion">any version string in the format [Major].[Minor].[Build].[Revision], like 5.3.3.1 or 5.4.*.*</param>
/// <exception cref="ArgumentException">if Major,Minor,Build, or Revision < -1</exception>
public Versioning(string strVersion)
{
if (!IsValidVersionStr(strVersion) || strVersion.Contains(";"))
throw new ArgumentException("Invalid Version String");
ParseVersion(strVersion, out this._MajorVersion, out this._MinorVersion, out this._BuildNumber, out this._RevisionNumber);
}
/// <summary>
/// Initialize Versioning with a single MajorVersion and MinorVersion.
/// </summary>
/// <param name="MajorVersion">Major Version</param>
/// <param name="MinorVersion">Minor Version</param>
/// <exception cref="ArgumentException">if Major,Minor,Build, or Revision < -1</exception>
public Versioning(int MajorVersion, int MinorVersion)
{
if (MajorVersion >= STAR_ALL && MinorVersion >= STAR_ALL)
{
_MajorVersion = MajorVersion;
_MinorVersion = MinorVersion;
}
else
throw new ArgumentException("MajorVersion or MinorVersion is invalid");
}
/// <summary>
/// Initialize Versioning with a single MajorVersion,MinorVersion, and BuildNumber.
/// </summary>
/// <param name="MajorVersion">Major Version</param>
/// <param name="MinorVersion">Minor Version</param>
/// <param name="BuildNumber">Build Number</param>
/// <exception cref="ArgumentException">if Major,Minor,Build, or Revision < -1</exception>
public Versioning(int MajorVersion, int MinorVersion, int BuildNumber)
{
if (MajorVersion >= STAR_ALL && MinorVersion >= STAR_ALL && _BuildNumber >= STAR_ALL)
{
_MajorVersion = MajorVersion;
_MinorVersion = MinorVersion;
_BuildNumber = BuildNumber;
}
else
throw new ArgumentException("MajorVersion,MinorVersion, or BuildNumber is invalid");
}
/// <summary>
/// Initialize Versioning with a single MajorVersion,MinorVersion,BuildNumber and RevisionNumber.
/// </summary>
/// <param name="MajorVersion">Major Version</param>
/// <param name="MinorVersion">Minor Version</param>
/// <param name="BuildNumber">Build Number</param>
/// <param name="RevisionNumber">Revision Number</param>
/// <exception cref="ArgumentException">if Major,Minor,Build, or Revision < -1</exception>
public Versioning(int MajorVersion, int MinorVersion, int BuildNumber, int RevisionNumber)
{
if (MajorVersion >= STAR_ALL && MinorVersion >= STAR_ALL && _BuildNumber >= STAR_ALL && RevisionNumber >= STAR_ALL)
{
_MajorVersion = MajorVersion;
_MinorVersion = MinorVersion;
_BuildNumber = BuildNumber;
_RevisionNumber = RevisionNumber;
}
else
throw new ArgumentException("MajorVersion,MinorVersion, BuildNumber, or RevisionNumber is invalid");
}
/// <summary>
/// Initialize Versioning with a .Net Version Object
/// </summary>
/// <param name="version">a .Net Version Object</param>
public Versioning(Version version)
{
_MajorVersion = version.Major;
_MinorVersion = version.Minor;
_BuildNumber = version.Build;
_RevisionNumber = version.Revision;
}
#endregion
#region Versioning Getter/Setter
/// <summary>
/// Set/Retrieve Version
/// </summary>
public String Version
{
get
{
return VersionToVersionString(_MajorVersion, _MinorVersion, _BuildNumber, _RevisionNumber);
}
set
{
if (IsValidVersionStr(value) && !value.Contains(";"))
ParseVersion(value, out this._MajorVersion, out this._MinorVersion, out this._BuildNumber, out this._RevisionNumber);
else
throw new ArgumentException("Invalid Version String");
}
}
#endregion
#region Public Static Helpers
/// <summary>
/// Gets a Versioning object for the Version Information of a File
/// </summary>
/// <param name="FileNameNPath">Full File Name and Path</param>
/// <returns>returns a new Versioning Object for a File, or null if error occured</returns>
public static Versioning GetFileVersioning(string FileNameNPath)
{
if (!string.IsNullOrEmpty(FileNameNPath) && System.IO.File.Exists(FileNameNPath))
{
try
{
FileVersionInfo info = FileVersionInfo.GetVersionInfo(FileNameNPath);
return new Versioning(info.FileMajorPart, info.FileMinorPart, info.FileBuildPart, info.FilePrivatePart);
}
catch (Exception) { /* ignore */ }
}
return null;
}
/// <summary>
/// Parses out a single Version from a string
/// </summary>
/// <param name="strVersion">pass in a Version format [Major].[Minor].[Build], like 5.3.3 or 5.4.*</param>
/// <param name="MajorVersion">returns an int or STAR_ALL</param>
/// <param name="MinorVersion">returns an int or STAR_ALL</param>
/// <param name="BuildNumber">returns an int or STAR_ALL</param>
/// <param name="RevisionNumber">returns an int or STAR_ALL</param>
public static void ParseVersion(string strVersion, out int MajorVersion, out int MinorVersion, out int BuildNumber, out int RevisionNumber)
{
if (!IsValidVersionStr(strVersion) || strVersion.Contains(";"))
throw new ArgumentException("Invalid Version String");
MajorVersion = STAR_ALL;
MinorVersion = STAR_ALL;
BuildNumber = STAR_ALL;
RevisionNumber = STAR_ALL;
string[] MajorMinorPossBuildVersion = strVersion.Split('.');
try
{
for (int i = 0; i < MajorMinorPossBuildVersion.Length; ++i)
{
if (i == 0)
{
if (MajorMinorPossBuildVersion[0] != "*")
MajorVersion = int.Parse(MajorMinorPossBuildVersion[0]);
}
else if (i == 1)
{
if (MajorMinorPossBuildVersion[1] != "*")
MinorVersion = int.Parse(MajorMinorPossBuildVersion[1]);
}
else if (i == 2)
{
if (MajorMinorPossBuildVersion[2] != "*")
BuildNumber = int.Parse(MajorMinorPossBuildVersion[2]);
}
else if (i == 3)
{
if (MajorMinorPossBuildVersion[2] != "*")
RevisionNumber = int.Parse(MajorMinorPossBuildVersion[3]);
}
}
}
catch (Exception) { /* Ignore */ }
}
/// <summary>
/// Turns Version Numbers into a Version String
/// </summary>
/// <param name="MajorVersion">Major Version</param>
/// <param name="MinorVersion">Minor Version, can be *</param>
/// <param name="BuildNumber">Build Number, can be * or UNINITIALIZED</param>
/// <returns>the Version String</returns>
public static string VersionToVersionString(int MajorVersion, int MinorVersion = STAR_ALL, int BuildNumber = STAR_ALL, int RevisionNumber = STAR_ALL)
{
string strRetVal = String.Empty;
if (MajorVersion >= STAR_ALL)
{
// Major Version
if (MajorVersion == STAR_ALL)
strRetVal += "*";
else
strRetVal += MajorVersion.ToString();
// Minor Version
if (MinorVersion >= STAR_ALL)
{
strRetVal += ".";
if (MinorVersion == STAR_ALL)
strRetVal += "*";
else
strRetVal += MinorVersion.ToString();
}
// Build Number
if (BuildNumber >= STAR_ALL)
{
strRetVal += ".";
if (BuildNumber == STAR_ALL)
strRetVal += "*";
else
strRetVal += BuildNumber.ToString();
}
// Revision Number
if (RevisionNumber >= STAR_ALL)
{
strRetVal += ".";
if (RevisionNumber == STAR_ALL)
strRetVal += "*";
else
strRetVal += RevisionNumber.ToString();
}
}
return strRetVal;
}
#endregion
#region Private Stats - Validation
private const string CharSet_AllowedNumeric = "0123456789";
private const string CharSet_AllowedVersionChars = CharSet_AllowedNumeric + "*;.";
/// <summary>
/// Generic Function to use with Allowed Character Sets above
/// </summary>
/// <param name="TextToEvaluate">string to evaluate</param>
/// <param name="TextToEvaluateWith">Pass in one of the legal character consts declared above</param>
/// <returns>true if valid, false otherwise</returns>
private static bool ContainsOnlyLegalChars(string TextToEvaluate, string TextToEvaluateWith)
{
foreach (char c in TextToEvaluate.ToCharArray())
{
bool bFound = (TextToEvaluateWith.IndexOf(c) >= 0);
if (!bFound)
return false;
}
return true;
}
/// <summary>
/// Used to Validate a Version string of format 12.1.12;12.2.*;12.2.1
/// </summary>
/// <param name="VersionStr">a Version String</param>
/// <returns>true if valid, false otherwise</returns>
public static bool IsValidVersionStr(string VersionStr)
{
if (String.IsNullOrEmpty(VersionStr))
{
return false;
}
else if (VersionStr.Length < 1 && VersionStr.Length > 14) // restrict Version String Length
{
return false;
}
else if (!ContainsOnlyLegalChars(VersionStr, CharSet_AllowedVersionChars))
{
return false;
}
else
{
return true;
}
}
#endregion
#region ICloneable Members
/// <summary>
/// Clone the Object
/// </summary>
/// <returns>a copy of this Versioning Object</returns>
public object Clone()
{
Versioning versioning = new Versioning(this._MajorVersion, this._MinorVersion, this._BuildNumber, this._RevisionNumber);
return versioning;
}
#endregion
#region IComparable Members
/// <summary>
/// Compare two Versioning Objects
/// </summary>
/// <param name="obj">a Versioning Object</param>
/// <returns>-1, 0, +1</returns>
public int CompareTo(object obj)
{
if (obj is Versioning)
{
Versioning v = (Versioning)obj;
//*.*.*
//*.2.*
//1.*.*
//1.1.*
//1.1.1
//2.2.2
//2.2.*
int nCompare = 0;
nCompare = this._MajorVersion.CompareTo(v._MajorVersion);
if(nCompare == 0)
nCompare = this._MinorVersion.CompareTo(v._MinorVersion);
if(nCompare == 0)
nCompare = this._BuildNumber.CompareTo(v._BuildNumber);
if (nCompare == 0)
nCompare = this._RevisionNumber.CompareTo(v._BuildNumber);
return nCompare;
}
else
{
throw new ArgumentException("object is not a Versioning");
}
}
#endregion
#region IVersionSupported Members
/// <summary>
/// Returns true if the Version String passed in is supported/matches Versioning for this object
/// </summary>
/// <param name="Version">a Versioning string to validate against</param>
/// <returns>true if supported, false otherwise</returns>
public bool IsSupported(string Version)
{
Versioning version = new Versioning(Version);
return IsSupported(version);
}
/// <summary>
/// Returns true if the Version passed in is supported/matches Versioning for this object
/// </summary>
/// <param name="Version">a Versioning Object to validate against</param>
/// <returns>true if supported, false otherwise</returns>
public bool IsSupported(Versioning Version)
{
if (Version != null)
{
int nCompare = this.CompareTo(Version);
if (nCompare == 0)
{
return true;
}
else if (nCompare == 1)
{
return false;
}
else if (nCompare == -1)
{
if (((this._MajorVersion == STAR_ALL) || (this._MajorVersion == Version._MajorVersion)) &&
((this._MinorVersion == STAR_ALL) || (this._MinorVersion == Version._MinorVersion)) &&
((this._BuildNumber == STAR_ALL) || (this._BuildNumber == Version._BuildNumber)) &&
((this._RevisionNumber == STAR_ALL) || (this._RevisionNumber == Version._RevisionNumber))
)
{
return true;
}
else
{
return false;
}
}
}
return false;
}
/// <summary>
/// Returns true if the Version passed in is supported/matches Versioning for this object
/// </summary>
/// <param name="Version">a Version Object to Validate against</param>
/// <returns>true if supported, false otherwise</returns>
public bool IsSupported(Version Version)
{
Versioning version = new Versioning(Version.Major, Version.Minor, Version.Build, Version.Revision);
return true;
}
#endregion
}
/// <remarks>
/// Allows us to easily parse/sort/search multiple versioning classes
/// </remarks>
public static class Versionings
{
/// <summary>
/// Used to parse multiple ";" seperated versions from a string
/// </summary>
/// <param name="strVersions">single/multiple version strings, seperated by ";", in the format [Major].[Minor].[Build].[Revision], like 5.3.3.1 or 5.4.*.*</param>
/// <returns>a sorted array of versionings or null if error occured</returns>
public static Versioning[] ParseVersions(string strVersions)
{
if (!Versioning.IsValidVersionStr(strVersions))
return null;
List<Versioning> RetValueVersions = new List<Versioning>();
string[] Versions = strVersions.Split(';');
foreach (string Version in Versions)
RetValueVersions.Add(new Versioning(Version));
RetValueVersions.Sort();
return RetValueVersions.ToArray();
}
#region IsSupportedFile
/// <summary>
/// Use this to find out if a File Version is supported by the passed in Versions string
/// </summary>
/// <param name="strVersions">single/multiple version strings, seperated by ";", in the format [Major].[Minor].[Build], like 5.3.3 or 5.4.*</param>
/// <param name="FileNameNPath">Full File Name and Path</param>
/// <returns>true if the File Version is supported by the Versions string</returns>
public static bool IsSupportedFile(string strVersions, string FileNameNPath)
{
return IsSupported(ParseVersions(strVersions), Versioning.GetFileVersioning(FileNameNPath));
}
/// <summary>
/// Use this to find out if a File Version is supported by the passed in Versions []
/// </summary>
/// <param name="Versions">single/multiple versioning objects</param>
/// <param name="FileNameNPath">Full File Name and Path</param>
/// <returns>true if the File Version is supported by the Versions string</returns>
public static bool IsSupportedFile(Versioning[] Versions, string FileNameNPath)
{
return IsSupported(Versions, Versioning.GetFileVersioning(FileNameNPath));
}
#endregion
#region IsSupported
/// <summary>
/// Pass in a Versions string, and a Version to check against. Returns true, if the Version is IVersionSupported by
/// the passed in Versions string.
/// </summary>
/// <param name="strVersions">single/multiple version strings, seperated by ";", in the format [Major].[Minor].[Build].[Revision], like 5.3.3 or 5.4.*</param>
/// <param name="strVersion">any version string in the format [Major].[Minor].[Build], like 5.3.3 or 5.4.*</param>
/// <returns>true, if a Versioning Object in the Versions returns true for IVersionSupported, false otherwise</returns>
public static bool IsSupported(string strVersions, string strVersion)
{
return IsSupported(ParseVersions(strVersions), new Versioning(strVersion));
}
/// <summary>
/// Pass in a single/multipe Versions object, and a Version object to check against. Returns true, if the Version is IVersionSupported by
/// the passed in Versions Objects.
/// </summary>
/// <param name="Versions">single/multiple versioning objects</param>
/// <param name="Version">single versioning object</param>
/// <returns>true, if a Versioning Object in the Versions returns true for IVersionSupported, false otherwise</returns>
public static bool IsSupported(Versioning[] Versions, Versioning Version)
{
// Let IVersionSupported do all the work
foreach (Versioning _version in Versions)
{
if (_version.IsSupported(Version))
return true;
}
return false;
}
/// <summary>
/// Pass in a single/multipe Versions object, and a Version object to check against. Returns true, if the Version is IVersionSupported by
/// the passed in Versions Objects.
/// </summary>
/// <param name="Versions">single/multiple versioning objects</param>
/// <param name="Version">single version object</param>
/// <returns>true, if a Versioning Object in the Versions returns true for IVersionSupported, false otherwise</returns>
public static bool IsSupported(Versioning[] Versions, Version Version)
{
// Let IVersionSupported do all the work
foreach (Versioning _version in Versions)
{
if (_version.IsSupported(Version))
return true;
}
return false;
}
#endregion
}
}

110
Process/PStartInfo.cs Normal file
View File

@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using Yaulw.Tools;
namespace Yaulw.Process
{
/// <remarks>
/// Helper Class to create ProcessStartInfo Objects
/// </remarks>
public static class PStartInfo
{
/// <summary>
/// Creates a simple ProcessStartInfo Object
/// </summary>
/// <param name="ExeFileNPath">Exe File and Path to execute</param>
/// <param name="CmdLine">CmdLine Params to process, optional</param>
/// <param name="bUseRunAs">If true, will set "RunAs" For the Process, to Run as Administrator</param>
/// <param name="WindowStyle">the windows style to initialize main window with</param>
/// <param name="bUseShellExecute">True to use Explorer.exe shellexecute, false otherise</param>
/// <returns>a ProcessStartInfo Object or null if error occured</returns>
public static ProcessStartInfo CreateProcess(string ExeFileNPath, string CmdLine = "", string WorkingDir = "", bool bUseRunAs = false, ProcessWindowStyle WindowStyle = ProcessWindowStyle.Normal, bool bUseShellExecute = true)
{
if (!String.IsNullOrEmpty(ExeFileNPath) && System.IO.File.Exists(ExeFileNPath))
{
ProcessStartInfo startInfo = new ProcessStartInfo(ExeFileNPath, CmdLine);
startInfo.WindowStyle = WindowStyle;
startInfo.UseShellExecute = bUseShellExecute;
if (bUseRunAs)
startInfo.Verb = "runas";
// Set up Working Directory, if one is found
if(!String.IsNullOrEmpty(WorkingDir))
startInfo.WorkingDirectory = PathNaming.PathEndsWithSlash(WorkingDir);
else
startInfo.WorkingDirectory = Path.GetDirectoryName(ExeFileNPath);
return startInfo;
}
return null;
}
/// <summary>
/// Creates an url ProcessStartInfo Object
/// </summary>
/// <param name="url">url to launche</param>
/// <returns>a ProcessStartInfo Object or null if error occured</returns>
public static ProcessStartInfo LaunchUrl(string url)
{
if (!String.IsNullOrEmpty(url))
{
ProcessStartInfo startInfo = new ProcessStartInfo(url);
startInfo.UseShellExecute = true;
return startInfo;
}
return null;
}
/// <summary>
/// Creates a CMD.Exe CommandLine Executable ProcessStartInfo Object
/// </summary>
/// <param name="scriptFileNPath">Full FileName and Path to script file to execute via CMD.exe</param>
/// <param name="bUseRunAs">If true, will set "RunAs" For the Process, to Run as Administrator</param>
/// <returns>a ProcessStartInfo Object or null if error occured</returns>
public static ProcessStartInfo CreateCMDScriptProcess(string scriptFileNPath, bool bUseRunAs = false)
{
if (!String.IsNullOrEmpty(scriptFileNPath) && System.IO.File.Exists(scriptFileNPath))
{
//The "/C" Tells Windows to Run The Command then Terminate
string strCmdLine = "/C " + '\"' + scriptFileNPath + '\"';
string WindowsSystem32Folder = System.Environment.GetFolderPath(Environment.SpecialFolder.System);
ProcessStartInfo startInfo = new ProcessStartInfo((WindowsSystem32Folder + "\\" + "CMD.exe"), strCmdLine);
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
if (bUseRunAs)
startInfo.Verb = "runas";
startInfo.WorkingDirectory = Path.GetDirectoryName(scriptFileNPath);
return startInfo;
}
return null;
}
/// <summary>
/// Creates a CMD.Exe CommandLine Executable ProcessStartInfo Object
/// </summary>
/// <param name="DosCommand">Dos Command to Execute</param>
/// <param name="bUseRunAs">If true, will set "RunAs" For the Process, to Run as Administrator</param>
/// <returns>a ProcessStartInfo Object or null if error occured</returns>
public static ProcessStartInfo CreateCMDDosCommandProcess(string DosCommand, bool bUseRunAs = false)
{
if (!String.IsNullOrEmpty(DosCommand))
{
//The "/C" Tells Windows to Run The Command then Terminate
string strCmdLine = "/C " + '\"' + DosCommand + '\"';
string WindowsSystem32Folder = System.Environment.GetFolderPath(Environment.SpecialFolder.System);
ProcessStartInfo startInfo = new ProcessStartInfo((WindowsSystem32Folder + "\\" + "CMD.exe"), strCmdLine);
//startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
if (bUseRunAs)
startInfo.Verb = "runas";
return startInfo;
}
return null;
}
}
}

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
}
}

309
Process/ProcessW.cs Normal file
View File

@@ -0,0 +1,309 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Diag = System.Diagnostics;
using System.Management;
namespace Yaulw.Process
{
/// <remarks>
/// Wrapper Class around System.Diagnostics's Process Class.
/// Helper functions to make sure that we can safely interact with Processes.
/// </remarks>
public static class ProcessW
{
#region Process Caching
/// <summary>
/// Process PID Lookup Cache - so that we can cache PIDs, we don't make a new system call
/// Use this Property to Cache Process PIDs Lookups
/// </summary>
public static List<uint> ProcessPidsRunningCache { get { return s_RunningProcessesPids; } }
private static List<uint> s_RunningProcessesPids = new List<uint>();
/// <summary>
/// Process Obj Lookup Cache - so that for processes with the same name, we don't make a new system call
/// Use this Property to Cache Process Obj Lookups
/// </summary>
public static Dictionary<string, List<Diag.Process>> ProcessObjsGetterCache { get { return s_processGetterCache; } }
private static Dictionary<string, List<Diag.Process>> s_processGetterCache = new Dictionary<string, List<Diag.Process>>();
/// <summary>
/// Clears the Process Obj Lookup Cache - Used in conjuction with AllRunningProcessesOf()
/// </summary>
public static void ClearProcessObjsGetterCache() { s_processGetterCache.Clear(); }
#endregion
#region Query For Processes
/// <summary>
/// Safe GetProcessById Function, to make sure that it returns a valid Process Object
/// </summary>
/// <param name="PID">the PID to get the Process Object for</param>
/// <param name="p">a valid Process obj, or null</param>
/// <returns>true if successful, false otherwise</returns>
public static bool GetProcessById(int PID, out Diag.Process p)
{
p = null;
try
{
p = Diag.Process.GetProcessById(PID);
return (p != null);
}
catch (Exception) { /*ignore */ }
return false;
}
/// <summary>
/// Quick Check to see if other Process of that Name Are running
/// </summary>
/// <param name="ProcessName">name of process</param>
/// <param name="bIgnoreVSHost">set to true to ignore Visual Studio's host .exe (debugger process)</param>
/// <returns>true, if only one Process of that Name is running, false otherwise</returns>
public static bool IsTheOnlyProcessRunning(string ProcessName, bool bIgnoreVSHost = true)
{
if (!string.IsNullOrEmpty(ProcessName))
{
// Visual Studio could be running this...
int nLength1 = Diag.Process.GetProcessesByName(ProcessName).Length;
int nLength2 = (bIgnoreVSHost)? 0 : Diag.Process.GetProcessesByName(ProcessName + ".vshost").Length;
int nProcessCount = nLength1 + nLength2;
return (nProcessCount == 0 || nProcessCount == 1);
}
return true;
}
/// <summary>
/// Use this to quickly retrieve all Running PID on this machine
/// * Excellent performance 10 MS *
/// </summary>
/// <returns>returns all running Pids</returns>
public static List<uint> AllRunningPids()
{
Diag.Process[] processes = Diag.Process.GetProcesses();
List<uint> allRunningPids = new List<uint>();
if (allRunningPids != null)
{
foreach (Diag.Process p in processes)
allRunningPids.Add((uint)p.Id);
}
return allRunningPids;
}
/// <summary>
/// Returns all Processes of that ProcessName
/// </summary>
/// <param name="ProcessName">name of process</param>
/// <param name="bUseLookupCache">If true, for .exe's in the Cache will return immediatly without a system call. Use ClearProcessObjsGetterCache() to clear Cache.</param>
/// <param name="bIgnoreVSHost">set to true to ignore Visual Studio's host .exe (debugger process)</param>
/// <returns>Returns all processes that match the process name, or empty array, if none found</returns>
public static Diag.Process[] AllRunningProcessesOf(string ProcessName, bool bUseLookupCache = false, bool bIgnoreVSHost = true)
{
if (!string.IsNullOrEmpty(ProcessName))
{
try
{
// Immediatly Return from Cache the Process Getter Calls * Performance Improvement *
if (bUseLookupCache && s_processGetterCache.ContainsKey(ProcessName))
return s_processGetterCache[ProcessName].ToArray();
// If a lookup cache is used, we won't deal with the complexity of also dealing with VSHost,
// so ignore this setting
if (bIgnoreVSHost && bUseLookupCache)
bIgnoreVSHost = true;
// Running Processes found
List<Diag.Process> runningProcess = new List<Diag.Process>();
// Regular Process Lookup...
Diag.Process[] processes = Diag.Process.GetProcessesByName(ProcessName);
if (processes != null && processes.Length > 0)
{
foreach (Diag.Process p in processes)
runningProcess.Add(p);
}
// Visual Studio could be running this...
if (!bIgnoreVSHost)
{
processes = Diag.Process.GetProcessesByName(ProcessName + ".vshost");
if (processes != null && processes.Length > 0)
{
foreach (Diag.Process p in processes)
runningProcess.Add(p);
}
}
// Immediatly Cache the Process Getter Calls
if (bUseLookupCache && !s_processGetterCache.ContainsKey(ProcessName))
{
s_processGetterCache[ProcessName] = new List<Diag.Process>();
s_processGetterCache[ProcessName].AddRange(runningProcess);
}
// Return the found Processes
return runningProcess.ToArray();
}
catch (Exception) { /* ignore */ }
}
return new Diag.Process[0]{}; // return empty array
}
#endregion
#region Process Exe FileName N CommandLine Getters
/// <summary>
/// Uses WMI to retrieve Process's FileNameNPath and the Command-Line Parameters for the specified Process
/// </summary>
/// <param name="ProcessId">a valid Pid to retrieve Command-line and Process FileName for</param>
/// <param name="ProcessFileNameNPath">passing out full process exe file name and path for pid, if found</param>
/// <param name="CommandLineParams">passing out CommandLine params for the Pid, if found</param>
/// <returns>true, if the process was found and at least ProcessFileNameNPath was written out, false otherwise</returns>
public static bool GetCommandLineArgumentsForProcessPID(int ProcessId, out string ProcessFileNameNPath, out string CommandLineParams)
{
ProcessFileNameNPath = String.Empty;
CommandLineParams = String.Empty;
try
{
// Use WMI to retrieve the info we need (.net does not provide any other way, it appears)
string wmiQuery = string.Format("SELECT CommandLine from Win32_Process WHERE ProcessId = {0}", ProcessId);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection retObjectCollection = searcher.Get();
if ((retObjectCollection != null) && (retObjectCollection.Count > 0))
{
foreach (ManagementObject retObject in retObjectCollection) // This will always be only 1 * retObjectCollection doesn't implement []
{
if (retObject != null) // to be even more save...
{
string strLocal = String.Empty;
if (retObject["CommandLine"] != null && !String.IsNullOrEmpty(retObject["CommandLine"].ToString()))
strLocal = retObject["CommandLine"].ToString().Trim();
if (!String.IsNullOrEmpty(strLocal))
{
// This should work
int firstQuotIndex = strLocal.IndexOf('\"');
int SecondQuotIndex = (firstQuotIndex >= 0) ? strLocal.IndexOf('\"', firstQuotIndex + 1) : -1;
// Pass out * if we at least have a Process FileNameNPath *
if (firstQuotIndex > -1 && SecondQuotIndex > -1)
{
ProcessFileNameNPath = Win32.Functions.GetLongFileNameNPathOrPath(strLocal.Substring(firstQuotIndex + 1, SecondQuotIndex - 1));
CommandLineParams = (strLocal.Length > SecondQuotIndex + 2) ? strLocal.Substring(SecondQuotIndex + 2) : String.Empty;
return true;
}
}
}
}
}
}
catch (Exception) { /* ignore */ }
return false;
}
/// <summary>
/// Usefull for making sure that the exact Process Image (including Command-Line Prms) is currently in a running state.
/// </summary>
/// <param name="runningProcesses">Pass in a list of Process[] where to search for ProcessFileNameNPath and CommandLineParams</param>
/// <param name="ProcessFileNameNPath">The exact Process FileName and Path (Image .exe) to find match for</param>
/// <param name="CommandLineParams">The exact Command-Line Parameters to find match for</param>
/// <param name="PID_Hint">a PID hint * to speed up look * caller can pass in a PID that 'most likely' is the PID we are looking for (Can be zero)</param>
/// <param name="process">If we found the process match, we'll pass out the process to the caller (runningProcesses[]), null otherwise</param>
/// <param name="indexFound">If we found the process match, we'll pass out the index to the caller (runningProcesses[]), -1 otherwise</param>
/// <returns>True, if exact Match was found, False Otherwise</returns>
public static bool FoundExactProcessExeNCommandLinePrmsInRunningProcesses(Diag.Process[] runningProcesses, string ProcessFileNameNPath, string CommandLineParams, int PID_Hint, out Diag.Process process, out int indexFound)
{
process = null;
indexFound = -1;
try
{
if (runningProcesses == null || runningProcesses.Length == 0)
return false;
if (PID_Hint < 0)
PID_Hint = 0;
bool bFoundProcessRunning = false;
// * For Performance Reasons * ProcessW.GetCommandLineArgumentsForProcessPID() takes a long time,
// Use PID_Hint first, to check if that PID is it
if (PID_Hint > 0)
{
for (int i = 0; i < runningProcesses.Length; ++i)
{
Diag.Process rProcess = runningProcesses[i];
if (rProcess != null && (rProcess.Id == PID_Hint))
{
string ProcessFileNameNPath_Local;
string CommandLineParams_Local;
if (ProcessW.GetCommandLineArgumentsForProcessPID(rProcess.Id, out ProcessFileNameNPath_Local, out CommandLineParams_Local))
{
// See if we find a match
if (ProcessFileExeNCommandLineParamsComparer_FoundMatch(ProcessFileNameNPath_Local, CommandLineParams_Local, ProcessFileNameNPath, CommandLineParams))
{
bFoundProcessRunning = true;
process = rProcess;
indexFound = i;
}
}
break;
}
}
}
// PID_Hint Worked, no need to continue...
if (bFoundProcessRunning)
return bFoundProcessRunning;
// Iterate all others
for (int i = 0; i < runningProcesses.Length; ++i)
{
Diag.Process rProcess = runningProcesses[i];
if (rProcess != null && (rProcess.Id != PID_Hint)) // Ignore PID_Hint * already been tried *
{
string ProcessFileNameNPath_Local;
string CommandLineParams_Local;
if (ProcessW.GetCommandLineArgumentsForProcessPID(rProcess.Id, out ProcessFileNameNPath_Local, out CommandLineParams_Local))
{
// See if we find a match
if (ProcessFileExeNCommandLineParamsComparer_FoundMatch(ProcessFileNameNPath_Local, CommandLineParams_Local, ProcessFileNameNPath, CommandLineParams))
{
bFoundProcessRunning = true;
process = rProcess;
indexFound = i;
break;
}
}
}
}
return bFoundProcessRunning;
}
catch (Exception) { /* ignore */ }
return false;
}
/// <summary>
/// Returns true if the passed in ProcessExeFileNameNPath, CommandLinePrms match _Left and _Right
/// </summary>
/// <param name="ProcessFileNameNPath_Left">Process FileNameNPath to compare to Right</param>
/// <param name="CommandLineParams_Left">CommandLine Parameters to compare to Right</param>
/// <param name="ProcessFileNameNPath_Right">Process FileNameNPath to compare to Left</param>
/// <param name="CommandLineParams_Right">CommandLine Parameters to compare to Left</param>
/// <returns>true if _left and _right match, false otherwise</returns>
public static bool ProcessFileExeNCommandLineParamsComparer_FoundMatch(string ProcessFileNameNPath_Left, string CommandLineParams_Left, string ProcessFileNameNPath_Right, string CommandLineParams_Right)
{
if ((String.Compare(ProcessFileNameNPath_Left.Trim(), ProcessFileNameNPath_Right.Trim(), true) == 0) &&
(String.Compare(CommandLineParams_Left.Trim(), CommandLineParams_Right.Trim(), true) == 0))
{
return true;
}
return false;
}
#endregion
}
}

212
Process/ServiceW.cs Normal file
View File

@@ -0,0 +1,212 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
using Yaulw.Win32;
using System.Runtime.InteropServices;
namespace Yaulw.Process
{
/// <remarks>
/// Wrapper Class around System.ServiceProcess's ServiceControl Class,
/// ~Little helper functions to make sure that we can safely interact with Services
/// </remarks>
public static class ServiceW
{
/// <summary>
/// Checks to see if the service exists on the local computer
/// </summary>
/// <param name="ServiceName">Name of Service to Check</param>
/// <returns>true if it exists, false otherwise</returns>
public static bool DoesServiceExist(string ServiceName)
{
try
{
ServiceController scm = new ServiceController(ServiceName);
if (scm != null && !String.IsNullOrEmpty(scm.ServiceName))
{
scm.Dispose();
return true;
}
}
catch (Exception) { /* ignore */ }
return false;
}
/// <summary>
/// Quick check to see if the service is running
/// </summary>
/// <param name="ServiceName">Name of Service to Check</param>
/// <returns>true if the service is running, false otherwise, if it doesn't exist returns true</returns>
public static bool IsServiceRunning(string ServiceName)
{
ServiceController scm = null;
try
{
scm = new ServiceController(ServiceName);
}
catch (Exception) { /* ignore */ }
if (scm != null)
{
bool bIsRunning = (scm.Status == ServiceControllerStatus.Running);
scm.Dispose();
return bIsRunning;
}
else
return false;
}
/// <summary>
/// Use this to Restart the Service
/// </summary>
/// <param name="ServiceName">Name of Service to Check</param>
/// <param name="bKillServiceByForceIfNeedBe">Set to true to try to force a Service Close by killing the Process, if the service is hanging</param>
/// <param name="WaitTimeoutInSeconds">Number of Seconds to wait for Service To Close/Start</param>
/// <param name="nStartupDelayInSeconds">Number of Seconds to wait inbetween closing and starting</param>
/// <returns>true if successful, false otherwise</returns>
public static bool RestartService(string ServiceName, bool bKillServiceByForceIfNeedBe = true, int WaitTimeoutInSeconds = 240, int nStartupDelayInSeconds = 2)
{
// Stop the Service
if (!StopService(ServiceName, bKillServiceByForceIfNeedBe, WaitTimeoutInSeconds))
return false;
// Delay Starting the Services for 'n' seconds
if (nStartupDelayInSeconds > 0)
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(nStartupDelayInSeconds));
// Start the Service
bool bIsStarted = StartService(ServiceName, WaitTimeoutInSeconds);
return bIsStarted;
}
/// <summary>
/// Use this to start a service
/// </summary>
/// <param name="ServiceName">Name of Service to Check</param>
/// <param name="WaitTimeoutInSeconds">Number of seconds to wait for Service to Start</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StartService(string ServiceName, int WaitTimeoutInSeconds = 240)
{
ServiceController scm = null;
try
{
scm = new ServiceController(ServiceName);
// Wait for 'Stopped' State
if (scm.Status != ServiceControllerStatus.Running)
{
scm.Start();
if (WaitTimeoutInSeconds > 0)
scm.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(WaitTimeoutInSeconds));
}
}
catch (Exception) { /* ignore */ }
if (scm != null)
{
bool bSuccess = (scm.Status == ServiceControllerStatus.Running);
scm.Dispose();
return bSuccess;
}
else
return false;
}
/// <summary>
/// Use this to stop a service
/// </summary>
/// <param name="ServiceName">Name of Service to Check</param>
/// <param name="bKillServiceByForceIfNeedBe">Set to true to try to force a Service Close by killing the Process, if the service is hanging</param>
/// <param name="WaitTimeoutInSeconds">Number of seconds to wait for Service to Stop</param>
/// <returns>true if successful, false otherwise</returns>
public static bool StopService(string ServiceName, bool bKillServiceByForceIfNeedBe = true, int WaitTimeoutInSeconds = 240)
{
ServiceController scm = null;
try
{
scm = new ServiceController(ServiceName);
// Wait for 'Stopped' State
if (scm.Status != ServiceControllerStatus.Stopped)
{
scm.Stop();
if (WaitTimeoutInSeconds > 0)
scm.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(WaitTimeoutInSeconds));
}
}
catch (Exception) { /* ignore */ }
try
{
if (scm != null)
{
bool bSuccess = (scm.Status == ServiceControllerStatus.Stopped);
// Always try Killing Service By Force, even if bSuccess is true,
// just to try to guarantee that the service is dead for good
if (bKillServiceByForceIfNeedBe)
bSuccess = StopServiceByForce(scm) || bSuccess;
scm.Dispose();
return bSuccess;
}
else
return false;
}
catch (Exception) { /* ignore */ }
return false;
}
/// <summary>
/// Brutal way to stop a service * Not Recommended *,
/// according to article:
/// </summary>
/// <see cref="http://community.bartdesmet.net/blogs/bart/archive/2004/10/16/438.aspx"/>
/// <see cref="http://stackoverflow.com/questions/884853/service-not-fully-stopped-after-servicecontroller-stop"/>
/// <param name="scm">a Service Controller Object whose PID you would like to kill</param>
/// <returns>true if successfull, false otherwise</returns>
private static bool StopServiceByForce(ServiceController scm)
{
Structures.SERVICE_STATUS_PROCESS ssp = new Structures.SERVICE_STATUS_PROCESS();
int ignored;
try
{
// Obtain information about the service, and specifically its hosting process,
// from the Service Control Manager.
if (!Advapi32.QueryServiceStatusEx(scm.ServiceHandle.DangerousGetHandle(), Definitions.SC_STATUS_PROCESS_INFO, ref ssp, Marshal.SizeOf(ssp), out ignored))
{
//throw new Exception("Couldn't obtain service process information.");
return false;
}
// A few quick sanity checks that what the caller wants is *possible*.
if (ssp.dwServiceType != Definitions.SERVICE_WIN32_OWN_PROCESS)
{
//throw new Exception("Can't wait for the service's hosting process to exit because there may be multiple services in the process (dwServiceType is not SERVICE_WIN32_OWN_PROCESS");
return false;
}
if ((ssp.dwServiceFlags & Definitions.SERVICE_RUNS_IN_SYSTEM_PROCESS) != 0)
{
//throw new Exception("Can't wait for the service's hosting process to exit because the hosting process is a critical system process that will not exit (SERVICE_RUNS_IN_SYSTEM_PROCESS flag set)");
return false;
}
if (ssp.dwProcessId == 0)
{
//throw new Exception("Can't wait for the service's hosting process to exit because the process ID is not known.");
return false;
}
// Try closing the Process Manually
bool bCloseSuccess = PStarter.KillProcess((uint)ssp.dwProcessId, false, 1, false, 2);
return bCloseSuccess;
}
catch (Exception) { /* ignore */ }
return false;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Yaulw")]
[assembly: AssemblyDescription("Yet Another Utility Library for .Net Windows")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Ideas To Action, Inc.")]
[assembly: AssemblyProduct("Yaul")]
[assembly: AssemblyCopyright("Copyright Daniel A. Romischer © 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2f7e3593-1fc7-45d8-b2f6-7e51d5161763")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

487
Registry/RegKey.cs Normal file
View File

@@ -0,0 +1,487 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using Yaulw.Tools;
namespace Yaulw.Registry
{
#region RegKey Enums
/// <summary>
/// Registry Root Key
/// </summary>
public enum HKEYRoot
{
ClassesRoot,
CurrentUser,
LocalMachine,
}
/// <summary>
/// Registry Sub Key
/// </summary>
public enum KeySub
{
Software,
Custom
}
#endregion
/// <remarks>
/// Wrapper Class around Registry Functionallity,
/// allows for easy reading/writing to the registry, especially HKEY_CURRENT_USER\Software
/// ~If you use this class directly make sure to call dispose(),
/// otherwise, use the Public Static Helper Functions to do the work for you
/// </remarks>
public class RegKey : IDisposable
{
#region Private Members
private RegistryKey _RegKey;
private bool _disposed = false;
#endregion
#region Constructors
/// <summary>
/// Use this to Open or Automatically Create the specified Key in CURRENT_USER\Software\Key.
/// </summary>
/// <param name="Key">Specify Key to Open</param>
/// <param name="bReadOnly">Set to true to Open, false to Create if not Exists</param>
public RegKey(string Key, bool bReadOnly = true) : this(HKEYRoot.CurrentUser, KeySub.Software, Key, bReadOnly) {}
/// <summary>
/// Use this to Open or Automatically Create a Registry Key
/// </summary>
/// <param name="root">specify registry root</param>
/// <param name="sub">specify a sub or custom</param>
/// <param name="Key">key you want to open / create </param>
/// <param name="bReadOnly">true if you want to force only reading it</param>
private RegKey(HKEYRoot root, KeySub sub, string Key, bool bReadOnly)
{
string KeyToOpen = String.Empty;
if (sub == KeySub.Custom)
KeyToOpen = Key;
else
KeyToOpen = sub.ToString() + "\\" + Key;
// Read Only Permission
RegistryKeyPermissionCheck permission = RegistryKeyPermissionCheck.ReadSubTree;
if (!bReadOnly)
permission = RegistryKeyPermissionCheck.ReadWriteSubTree;
// Open or Create, if it doesn't exist and we have writable set
switch (root)
{
case HKEYRoot.ClassesRoot:
if (bReadOnly)
_RegKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(KeyToOpen);
else
_RegKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(KeyToOpen, permission);
break;
case HKEYRoot.CurrentUser:
if (bReadOnly)
_RegKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(KeyToOpen, permission);
else
_RegKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(KeyToOpen, permission);
break;
case HKEYRoot.LocalMachine:
if (bReadOnly)
_RegKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(KeyToOpen, permission);
else
_RegKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(KeyToOpen, permission);
break;
}
}
/// <summary>
/// Finalizer
/// </summary>
~RegKey()
{
Dispose(true);
}
#endregion
#region GetValue Registry Functions
/// <summary>
/// Generic Registry KeyValue Getter Function
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="strKeyValue">The Value to get from the Registry</param>
/// <param name="DefaultValue">Default value to use if nothing was retrieved * Error occured *</param>
/// <returns>Value found or Default Value</returns>
public T GetVal<T>(string strKeyValue, T DefaultValue)
{
T retVal = DefaultValue;
try
{
if (_RegKey != null)
{
object keyvalue = _RegKey.GetValue(strKeyValue);
string strvalue = string.Empty;
if (ObjTool.IsNotNullAndNotEmpty(keyvalue))
{
#region First Handle the Value as a string
// Handle Multi-Strings
if (keyvalue is object[])
{
string keyVal2 = string.Empty;
string[] strVal2 = (string[])keyvalue;
foreach (string str in strVal2)
{
keyVal2 += str;
}
strvalue = keyVal2;
}
else
{
// Handle Single-Strings
strvalue = keyvalue.ToString();
}
#endregion
// Now cast the Object Return type * Handle each object differently *
retVal = ObjTool.ConvertStringToObj<T>(strvalue);
}
}
}
catch (Exception) { /* ignore */ }
return retVal;
}
/// <summary>
/// Binary Registry KeyValue Getter Function
/// </summary>
/// <param name="strKeyValue">The Value to get from the Registry</param>
/// <returns>an array of Bytes found in the Registry, or null if none found, or error occured</returns>
public byte[] GetVal(string strKeyValue)
{
byte[] retVal = null;
try
{
string StringValue = GetVal<System.String>(strKeyValue, String.Empty);
if (!String.IsNullOrEmpty(StringValue))
{
Byte[] ByteValue = new Byte[StringValue.Length];
for (int i = 0; i < ByteValue.Length; ++i)
{
string strByte = System.Convert.ToString(StringValue[i]);
ByteValue[i] = byte.Parse(strByte);
}
retVal = ByteValue;
}
}
catch (Exception) { /* ignore */ }
return retVal;
}
#endregion
#region SetValue Registry Functions
/// <summary>
/// Generic Registry KeyValue Setter Function
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="strKeyValue">The Value to write to in the Registry</param>
/// <param name="Value">The Value to set to the Registry</param>
/// <returns>true if successful, false otherwise</returns>
public bool SetVal<T>(string strKeyValue, T Value)
{
bool bRetVal = false;
try
{
if (_RegKey != null)
{
if (Value is System.Int32)
{
_RegKey.SetValue(strKeyValue, Value, RegistryValueKind.DWord);
}
else if (Value is System.Int64)
{
_RegKey.SetValue(strKeyValue, Value, RegistryValueKind.QWord);
}
else
{
_RegKey.SetValue(strKeyValue, Value, RegistryValueKind.String);
}
bRetVal = true;
}
}
catch (Exception) { /* ignore */ }
return bRetVal;
}
/// <summary>
/// Generic Registry KeyValue Setter Function
/// </summary>
/// <param name="strKeyValue">The Value to write to in the Registry</param>
/// <param name="ByteValue">A binary array of bytes to write to the Registry</param>
/// <returns>true if successful, false otherwise</returns>
public bool SetVal(string strKeyValue, byte[] ByteValue)
{
try
{
_RegKey.SetValue(strKeyValue, ByteValue, RegistryValueKind.Binary);
return true;
}
catch (Exception) { /* ignore */ }
return false;
}
#endregion
#region Delete Registry Function
/// <summary>
/// Registry KeyValue Delete Function
/// </summary>
/// <param name="strKeyValue">The Value to delete in the Registry</param>
/// <returns>true if successful, false otherwise</returns>
public bool DeleteKey(string strKeyValue)
{
try
{
if (_RegKey != null)
{
_RegKey.DeleteValue(strKeyValue, false);
return true;
}
}
catch (Exception) { /* ignore */ }
return false;
}
#endregion
#region Public Static Helper Functions
/// <summary>
/// Generic Static Registry Writer Function * Allows writing to HKEY\CURRENT_USER\SOFTWARE *
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="SubKey">SubKey i.e. Microsoft, Microsoft\Windows</param>
/// <param name="KeyValue">Value to write to</param>
/// <param name="Value">Value to write</param>
/// <returns>true if successful, false otherwise</returns>
public static bool SetKey<T>(String SubKey, String KeyValue, T Value)
{
bool bRetVal = false;
using (RegKey reg = new RegKey(HKEYRoot.CurrentUser, KeySub.Software, SubKey, false))
{
bRetVal = reg.SetVal<T>(KeyValue, Value);
}
return bRetVal;
}
/// <summary>
/// Generic Static Registry Writer For Binary Function * Allows writing to HKEY\CURRENT_USER\SOFTWARE *
/// </summary>
/// <param name="SubKey">SubKey i.e. Microsoft, Microsoft\Windows</param>
/// <param name="KeyValue">Value to write to</param>
/// <param name="ByteValue">Binary Value to write</param>
/// <returns>true if successful, false otherwise</returns>
public static bool SetKey(String SubKey, String KeyValue, byte[] ByteValue)
{
bool bRetVal = false;
using (RegKey reg = new RegKey(HKEYRoot.CurrentUser, KeySub.Software, SubKey, false))
{
bRetVal = reg.SetVal(KeyValue, ByteValue);
}
return bRetVal;
}
/// <summary>
/// Generic Static Registry Writer Function * Allows writing to any key *
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="rootKey">RootKey as defined in this Class</param>
/// <param name="SubKey">SubKey i.e. Software, Software\Microsoft</param>
/// <param name="KeyValue">Value to write to</param>
/// <param name="Value">Value to write</param>
/// <returns>true if successful, false otherwise</returns>
public static bool SetKey<T>(HKEYRoot rootKey, String SubKey, String KeyValue, T Value)
{
bool bRetVal = false;
using (RegKey reg = new RegKey(rootKey, KeySub.Custom, SubKey, false))
{
bRetVal = reg.SetVal<T>(KeyValue, Value);
}
return bRetVal;
}
/// <summary>
/// Generic Static Registry Writer For Binary Function * Allows writing to any key *
/// </summary>
/// <param name="rootKey">RootKey as defined in this Class</param>
/// <param name="SubKey">SubKey i.e. Software, Software\Microsoft</param>
/// <param name="KeyValue">Value to write to</param>
/// <param name="ByteValue">Binary Value to write</param>
/// <returns>true if successful, false otherwise</returns>
public static bool SetKey(HKEYRoot rootKey, String SubKey, String KeyValue, byte[] ByteValue)
{
bool bRetVal = false;
using (RegKey reg = new RegKey(rootKey, KeySub.Custom, SubKey, false))
{
bRetVal = reg.SetVal(KeyValue, ByteValue);
}
return bRetVal;
}
/// <summary>
/// Static Registry Delete Function * Allows Deleting from HKEY\CURRENT_USER\SOFTWARE *
/// </summary>
/// <param name="SubKey">SubKey i.e. Microsoft, Microsoft\Windows</param>
/// <param name="KeyValue">Value to delete</param>
/// <returns>true if successful, false otherwise</returns>
public static bool DeleteKey(String SubKey, String KeyValue)
{
bool bRetVal = false;
using (RegKey reg = new RegKey(HKEYRoot.CurrentUser, KeySub.Software, SubKey, false))
{
bRetVal = reg.DeleteKey(KeyValue);
}
return bRetVal;
}
/// <summary>
/// Static Registry Delete Function * Allows Deleting any key *
/// </summary>
/// <param name="rootKey">RootKey as defined in this Class</param>
/// <param name="SubKey">SubKey i.e. Software, Software\Microsoft</param>
/// <param name="KeyValue">Value to delete</param>
/// <returns>true if successful, false otherwise</returns>
public static bool DeleteKey(HKEYRoot rootKey, String SubKey, String KeyValue)
{
bool bRetVal = false;
using (RegKey reg = new RegKey(rootKey, KeySub.Custom, SubKey, false))
{
bRetVal = reg.DeleteKey(KeyValue);
}
return bRetVal;
}
/// <summary>
/// Generic Static Registry Reader Function * Allows reading from HKEY\CURRENT_USER\SOFTWARE *
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="SubKey">SubKey i.e. Microsoft, Microsoft\Windows</param>
/// <param name="KeyValue">Value to write to</param>
/// <param name="DefaultValue">Default Value to return if none found or error occured</param>
/// <returns>true if successful, false otherwise</returns>
public static T GetKey<T>(String SubKey, String KeyValue, T DefaultValue)
{
T tRetVal = default(T);
using (RegKey reg = new RegKey(HKEYRoot.CurrentUser, KeySub.Software, SubKey, true))
{
tRetVal = reg.GetVal<T>(KeyValue, DefaultValue);
}
return tRetVal;
}
/// <summary>
/// Generic Static Registry Reader For Binary Function * Allows reading from HKEY\CURRENT_USER\SOFTWARE *
/// </summary>
/// <param name="SubKey">SubKey i.e. Microsoft, Microsoft\Windows</param>
/// <param name="KeyValue">Value to write to</param>
/// <returns>true if successful, false otherwise</returns>
public static Byte[] GetKey(String SubKey, String KeyValue)
{
Byte[] retByte = null;
using (RegKey reg = new RegKey(HKEYRoot.CurrentUser, KeySub.Software, SubKey, true))
{
retByte = reg.GetVal(KeyValue);
}
return retByte;
}
/// <summary>
/// Generic Static Registry Reader Function * Allows reading from any key *
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="rootKey">RootKey as defined in this Class</param>
/// <param name="SubKey">SubKey i.e. Software, Software\Microsoft</param>
/// <param name="KeyValue">Value to write to</param>
/// <param name="DefaultValue">Default Value to return if none found or error occured</param>
/// <returns>true if successful, false otherwise</returns>
public static T GetKey<T>(HKEYRoot rootKey, String SubKey, String KeyValue, T DefaultValue)
{
T tRetVal = default(T);
using (RegKey reg = new RegKey(rootKey, KeySub.Custom, SubKey, true))
{
tRetVal = reg.GetVal<T>(KeyValue, DefaultValue);
}
return tRetVal;
}
/// <summary>
/// Generic Static Registry Reader For Binary Function * Allows reading from any key *
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="rootKey">RootKey as defined in this Class</param>
/// <param name="SubKey">SubKey i.e. Software, Software\Microsoft</param>
/// <param name="KeyValue">Value to write to</param>
/// <returns>true if successful, false otherwise</returns>
public static Byte[] GetKey(HKEYRoot rootKey, String SubKey, String KeyValue)
{
Byte[] retByte = null;
using (RegKey reg = new RegKey(rootKey, KeySub.Custom, SubKey, true))
{
retByte = reg.GetVal(KeyValue);
}
return retByte;
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose the Registry Handle
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose the Registry Handle
/// </summary>
/// <param name="disposing">true, if called from within</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
#if NET4
if (disposing)
{
if (_RegKey != null)
_RegKey.Dispose(); // Works in .Net 4.0 Only
}
#endif
// Indicate that the instance has been disposed.
_RegKey = null;
_disposed = true;
}
}
#endregion
}
}

35
Structs/sbstring.cs Normal file
View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Utilities.GenericUtilities.Structs
{
/// <summary>
/// String Builder Wrapper struct in order to be able to use +=
/// </summary>
public struct sbstring
{
// StringBuilder to wrapp
private StringBuilder _sb;
public static string operator+ (sbstring op1, string op2)
{
op1.SBInit();
op1._sb.Append(op2);
return op1._sb.ToString();
}
//public static sbstring operator +(sbstring op1, string op2)
//{
// op1._sb.Append(op2);
// return op1;
//}
/// <summary>
/// Call this function to initialize the StringBuilder * must be called by all ops first *
/// </summary>
private void SBInit() { if (_sb == null) _sb = new StringBuilder(); }
}
}

507
Thread/DispatcherThread.cs Normal file
View File

@@ -0,0 +1,507 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sys = System.Threading;
using System.Reflection;
using Yaulw.WPF;
using System.Threading;
using System.Windows.Threading;
using Yaulw.Other;
namespace Yaulw.Thread
{
/// <summary>
///
/// </summary>
public enum DispatcherThreatType
{
WPF,
// Winforms // ~Not implmented
// Silverlight? // ~Not implemented
}
/// <summary>
///
/// </summary>
public class WindowType
{
public Type T;
public Enum Key;
public bool IsSingleton;
public bool IsPerformanceLoaded;
public WindowType(Type t, Enum Key, bool IsSingleton, bool IsPerformanceLoaded)
{
this.T = t;
this.Key = Key;
this.IsSingleton = IsSingleton;
this.IsPerformanceLoaded = IsPerformanceLoaded;
}
}
/// <summary>
///
/// </summary>
public class WindowAttributes
{
public IntPtr hWndOwner;
public uint Height;
public uint Width;
public int Top;
public int Left;
public string Title;
public WindowAttributes(IntPtr hWndOwner, uint Height, uint Width, int Top, int Left, string Title)
{
this.hWndOwner = hWndOwner;
this.Height = Height;
this.Width = Width;
this.Top = Top;
this.Left = Left;
this.Title = Title;
}
public WindowAttributes(IntPtr hWndOwner, int Top, int Left)
{
this.hWndOwner = hWndOwner;
this.Height = 0;
this.Width = 0;
this.Top = Top;
this.Left = Left;
this.Title = String.Empty;
}
public WindowAttributes(IntPtr hWndOwner)
{
this.hWndOwner = hWndOwner;
this.Height = 0;
this.Width = 0;
this.Top = int.MinValue;
this.Left = int.MinValue;
this.Title = String.Empty;
}
}
#region Window Manager Definition
/// <summary>
/// Abstract Base Class all Window Managers must inherit from.
///
/// </summary>
public abstract class WindowManager : IDisposable
{
#region Private Members
private Dictionary<WindowType, List<object>> s_WindowsToManage = new Dictionary<WindowType, List<object>>();
#endregion
#region Construction
/// <summary>
/// Construct a Window Manager Object
/// </summary>
/// <param name="dispatcher">Thread Dispatcher Object</param>
/// <param name="windowTypes">Window Types this WindowManager is managing</param>
/// <param name="PerformanceLoad">true, to load performance enabled windows upon construction</param>
public WindowManager(Dispatcher dispatcher, WindowType[] windowTypes, bool PerformanceLoad)
{
Dispatcher = dispatcher;
WindowTypes = windowTypes;
if (Dispatcher == null)
throw new ArgumentException("dispatcher can't be null");
if (windowTypes == null || windowTypes.Length < 1)
throw new ArgumentException("windowTypes can't be null or empty");
// Add All Window Types
foreach (WindowType type in windowTypes)
{
// Add the Type to be managed
AddWindowTypeToManage(type);
// perform performance optimization
if (PerformanceLoad && type.IsPerformanceLoaded)
{
object o = CreateInstance(type);
AddObject(type, o);
}
}
}
#endregion
#region Public Properties
/// <summary>
/// Returns the Dispatcher Thread responsible for this Window Manager
/// </summary>
public Dispatcher Dispatcher { get; private set; }
/// <summary>
/// Returns all the Window Types that have been set to be managed by this Window Manager
/// </summary>
public WindowType[] WindowTypes { get; private set; }
#endregion
#region Protected Common Window Object Operations
/// <summary>
/// Create a new Object Instance of type
/// </summary>
/// <param name="window">type of object to create</param>
/// <returns>a new object for type, or null</returns>
protected object CreateInstance(WindowType window)
{
object o = null;
if (window != null)
o = Activator.CreateInstance(window.T);
return o;
}
/// <summary>
/// Create a new Object Instance of type
/// </summary>
/// <param name="windowKey">type of object to create</param>
/// <returns>a new object for type, or null</returns>
protected object CreateInstance(Enum windowKey)
{
return CreateInstance(GetType(windowKey));
}
/// <summary>
///
/// </summary>
/// <param name="windowKey"></param>
/// <returns></returns>
protected List<object> GetObjects(Enum windowKey)
{
foreach (WindowType type in s_WindowsToManage.Keys)
{
if (type.Key.ToString() == windowKey.ToString())
return s_WindowsToManage[type];
}
return null;
}
/// <summary>
///
/// </summary>
/// <param name="window"></param>
/// <returns></returns>
protected List<object> GetObjects(WindowType window)
{
foreach (WindowType type in s_WindowsToManage.Keys)
{
if (type.Key.ToString() == window.Key.ToString())
return s_WindowsToManage[type];
}
return null;
}
/// <summary>
///
/// </summary>
/// <param name="windowKey"></param>
/// <returns></returns>
protected WindowType GetType(Enum windowKey)
{
foreach (WindowType type in s_WindowsToManage.Keys)
{
if (type.Key.ToString() == windowKey.ToString())
return type;
}
return null;
}
/// <summary>
///
/// </summary>
/// <param name="window"></param>
/// <param name="o"></param>
/// <returns></returns>
protected bool AddObject(WindowType window, object o)
{
if (AddWindowTypeToManage(window))
{
List<object> objects = GetObjects(window);
if (objects.Count == 0)
{
objects.Add(o);
return true;
}
else if (objects.Count > 0 && !window.IsSingleton)
{
objects.Add(o);
return true;
}
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="windowKey"></param>
/// <param name="o"></param>
/// <returns></returns>
protected bool AddObject(Enum windowKey, object o)
{
WindowType type = GetType(windowKey);
if (type != null)
{
List<object> objects = GetObjects(windowKey);
if (objects.Count == 0)
{
objects.Add(o);
return true;
}
else if (objects.Count > 0 && !type.IsSingleton)
{
objects.Add(o);
return true;
}
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="window"></param>
/// <returns></returns>
protected bool DeleteObject(WindowType window)
{
List<object> objects = GetObjects(window);
if (objects != null && objects.Count > 0)
{
int nIndex = objects.Count - 1;
if (objects[nIndex] is IDisposable)
((IDisposable)objects[nIndex]).Dispose();
objects.RemoveAt(nIndex);
return true;
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="windowKey"></param>
/// <returns></returns>
protected bool DeleteObject(Enum windowKey)
{
List<object> objects = GetObjects(windowKey);
if (objects != null && objects.Count > 0)
{
int nIndex = objects.Count - 1;
if (objects[nIndex] is IDisposable)
((IDisposable)objects[nIndex]).Dispose();
objects.RemoveAt(nIndex);
return true;
}
return false;
}
/// <summary>
///
/// </summary>
protected void ClearAllObjects()
{
// Iterate thru all objects and call dispose on them if they support it,
// then clear main dictionary
foreach (WindowType type in s_WindowsToManage.Keys)
while (DeleteObject(type)) ;
s_WindowsToManage.Clear();
}
/// <summary>
///
/// </summary>
/// <param name="window"></param>
/// <returns></returns>
protected bool AddWindowTypeToManage(WindowType window)
{
if (window != null && !IsWindowTypeManaged(window))
s_WindowsToManage[window] = new List<object>();
return (IsWindowTypeManaged(window));
}
/// <summary>
///
/// </summary>
/// <param name="window"></param>
/// <returns></returns>
protected bool IsWindowTypeManaged(WindowType window)
{
if (window != null)
{
foreach (WindowType type in s_WindowsToManage.Keys)
{
if (type.Key.ToString() == window.Key.ToString())
return true;
}
}
return false;
}
#endregion
#region Abtract Methods
public delegate object ShowDelegate(Enum windowKey, WindowAttributes attributes, object tag);
public abstract object ShowWindow(Enum windowKey, WindowAttributes attributes, object tag);
public abstract object ShowDialog(Enum windowKey, WindowAttributes attributes, object tag);
public delegate bool HideCloseDelegate(Enum windowKey);
public abstract bool HideWindow(Enum windowKey);
public abstract bool CloseWindow(Enum windowKey);
public delegate bool ActionDelegate(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action);
public abstract bool RunAction(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action);
public abstract void Dispose();
#endregion
#region Public Methods
/// <summary>
/// Get All Window Objects for a Window, in a readonly fashion
/// </summary>
/// <param name="windowKey"></param>
/// <returns></returns>
public object[] GetAllWindowObjectsForWindow(Enum windowKey)
{
List<object> objects = GetObjects(windowKey);
if (objects != null)
return objects.ToArray();
else
return null;
}
#endregion
}
#endregion
#region Dispatcher Thread
/// <summary>
///
/// </summary>
static class DispatcherThread
{
#region Private Static Members
private static Sys.Thread s_DispatcherThread = null;
private static bool s_DispatcherThreadIsInitialized = false;
private static WPFWindowManager s_wpfWindowManager = null;
private static DispatcherThreatType s_useWindowManagerType = DispatcherThreatType.WPF;
private static WindowType[] s_windowTypes = null;
private static bool s_PerformPerformanceLoad = false;
#endregion
#region Private Static Methods
/// <summary>
/// Message Loop Thread for ButtonForm
/// </summary>
private static void ThreadProc()
{
// Create WindowManager Object on this thread *Allow global access to the object*
if (s_useWindowManagerType == DispatcherThreatType.WPF)
s_wpfWindowManager = new WPFWindowManager(Dispatcher.CurrentDispatcher, s_windowTypes, s_PerformPerformanceLoad);
s_DispatcherThreadIsInitialized = true; // always set to true to allow caller to exit out
if (s_wpfWindowManager != null)
{
//Enter Dispatcher Message Loop
System.Windows.Threading.Dispatcher.Run();
}
}
#endregion
#region Public Static Methods
/// <summary>
/// Retrieve the Window Manager for this Dispatcher Thread
/// </summary>
/// <returns>a valid window Manager or null, if none</returns>
public static WindowManager GetWMForDispatcher()
{
if (s_DispatcherThreadIsInitialized)
{
if (s_useWindowManagerType == DispatcherThreatType.WPF && s_wpfWindowManager != null)
return s_wpfWindowManager;
}
return null;
}
/// <summary>
/// Use this function to start the Dispatcher ThreadProc(above), if needed. COM+ can shutdown the thread anytime,
/// we need to make sure that the thread is alive BEFORE calling WindowManager
/// </summary>
public static void Start(DispatcherThreatType threatType, WindowType[] windowTypes, bool PerformPerformanceLoad, bool bWait)
{
if (s_DispatcherThread != null && s_DispatcherThread.IsAlive)
{
return;
}
else
{
s_DispatcherThreadIsInitialized = false;
// Specify Thread Attributes
s_useWindowManagerType = threatType;
s_windowTypes = windowTypes;
s_PerformPerformanceLoad = PerformPerformanceLoad;
// Start a new Thread so it can become the Message Loop
s_DispatcherThread = new Sys.Thread(new Sys.ThreadStart(DispatcherThread.ThreadProc));
// GUI components require the thread to be STA; otherwise throws an error
s_DispatcherThread.SetApartmentState(ApartmentState.STA);
s_DispatcherThread.Start();
// Make sure the Application Object is running
// (COM will eventually just time out otherwise)
if (bWait) // Syncronous call
{
while (!s_DispatcherThreadIsInitialized)
System.Threading.Thread.Sleep(20);
}
}
}
/// <summary>
/// Terminates all ButtonForm Objects and the Message Dispatcher Thread *do this only on shutdown*
/// </summary>
public static void Stop()
{
if (s_DispatcherThreadIsInitialized)
{
// Enforce that all WindowManagers support IDispose
if (s_wpfWindowManager != null)
{
s_wpfWindowManager.Dispose();
s_wpfWindowManager = null;
}
s_DispatcherThread.Abort();
s_DispatcherThreadIsInitialized = false;
s_DispatcherThread = null;
}
}
#endregion
}
#endregion
}

143
Thread/SingleThreadTimer.cs Normal file
View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
namespace Yaulw.Thread
{
/// <summary>
/// Single Threaded Timer * only calls the elapsed event handler once and only
/// will call it again, if the elapsed event handler returns
/// </summary>
public class SingleThreadTimer
{
#region Private Members
private STElapsedEventHandler _elapsedHandler = null;
private uint _IntervalMilliseconds = 0;
private System.Threading.Thread _thread = null;
#endregion
#region Construction
/// <summary>
/// Creates a new Single-threaded System.Timer
/// </summary>
/// <param name="ElapsedHandler">Event Handler for Timer</param>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
public SingleThreadTimer(STElapsedEventHandler ElapsedHandler, uint IntervalMilliseconds, bool StartEnabled)
{
_elapsedHandler = ElapsedHandler;
_IntervalMilliseconds = IntervalMilliseconds;
if (_elapsedHandler == null || _IntervalMilliseconds == 0)
throw new ArgumentException("Invalid ElapsedHandler or Milliseconds. ElapsedHandler can not be null. Milliseconds can not be 0.");
if (StartEnabled)
Start();
}
#endregion
#region Private Helpers
/// <summary>
/// Main DoWork() Function, calls the ElapsedHandler at every interval
/// * Single threaded * ElapsedHandler will only get called again, once it returns
/// </summary>
private void STimerThreadMethod()
{
do
{
if (_IntervalMilliseconds > 0)
System.Threading.Thread.Sleep((int)_IntervalMilliseconds);
if (_elapsedHandler != null)
_elapsedHandler(this, new STElapsedEventArgs(DateTime.Now));
}
while (true);
}
#endregion
#region Public Delegates
/// <summary>
/// ElapsedEvent Handler is called when the time interval elapsed
/// </summary>
/// <param name="sender">Sends the STimer Object</param>
/// <param name="e">sends the Timestampe when the interval elapsed</param>
public delegate void STElapsedEventHandler(object sender, STElapsedEventArgs e);
/// <summary>
/// ElapsedEventArgs are called with the time stamp when the Event was raised
/// </summary>
public class STElapsedEventArgs : EventArgs
{
public DateTime SignalTime { get; private set; }
public STElapsedEventArgs(DateTime SignalTime) { this.SignalTime = SignalTime; }
}
#endregion
#region Public Methods
/// <summary>
/// Manually Start the STimer
/// </summary>
public bool Start()
{
Stop(); // First Stop(), an existing Timer
return Start(_IntervalMilliseconds);
}
/// <summary>
/// Manually Start the STimer at a new Interval
/// </summary>
/// <param name="tsInterval">Interval as a TimeSpan</param>
public bool Start(TimeSpan tsInterval)
{
Stop(); // First Stop(), an existing Timer
return Start((uint)tsInterval.TotalMilliseconds);
}
/// <summary>
/// Manually Start the STimer at a new Interval
/// </summary>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
public bool Start(uint IntervalMiliseconds)
{
try
{
Stop(); // First Stop(), an existing Timer
if (IntervalMiliseconds > 0)
_IntervalMilliseconds = IntervalMiliseconds;
if (_thread == null)
_thread = TStarter.StartThread(STimerThreadMethod, ("STimer-" + _elapsedHandler.Method.Name), System.Threading.ApartmentState.MTA, false, System.Threading.ThreadPriority.Normal);
return ((_thread != null) && (_thread.IsAlive));
}
catch (Exception) { /* ignore */ }
return false;
}
/// <summary>
/// Manually Stop the STimer
/// </summary>
public void Stop()
{
try
{
if (_thread != null)
_thread.Abort();
}
catch (Exception) { /* ignore */ }
_thread = null;
}
#endregion
}
}

140
Thread/TStarter.cs Normal file
View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections.Specialized;
namespace Yaulw.Thread
{
/// <remarks>
/// Used to Manage/Launch Threads In an Application
/// </remarks>
public static class TStarter
{
#region Public Delegates
/// <summary>
/// Thread Delegate with a single Object as a parameter
/// </summary>
/// <param name="o">object to be passed to Delegate</param>
public delegate void ParameterizedThreadMethod(object o);
/// <summary>
/// No Parameter Thread Delegate
/// </summary>
public delegate void ThreadMethod();
#endregion
#region Private Static Members
private static Dictionary<string, System.Threading.Thread> _StartedNamedThreads = new Dictionary<string, System.Threading.Thread>();
#endregion
#region Public Statics
/// <summary>
/// Starts a Parameterized thread
/// </summary>
/// <param name="method">specifcy a method to invoke</param>
/// <param name="parameter">specify a parameter to pass to the method</param>
/// <param name="threadName">If you specify a ThreadName, it must be Unique to the Application</param>
/// <param name="Apartment">ApartmentState</param>
/// <param name="IsBackground">Is Background Thread</param>
/// <param name="priority">set thread priority</param>
/// <returns>a thread object if successful, null otherwise</returns>
public static System.Threading.Thread StartParameterizedThread(ParameterizedThreadMethod method, object parameter, string threadName = "", ApartmentState Apartment = ApartmentState.MTA, bool IsBackground = false, ThreadPriority priority = ThreadPriority.Normal)
{
// If a threadName is defined, make sure that it is unique to the application
if (!String.IsNullOrEmpty(threadName) && _StartedNamedThreads.ContainsKey(threadName))
return null;
System.Threading.Thread thread = null;
if (method != null && parameter != null)
{
thread = new System.Threading.Thread(new ParameterizedThreadStart(method));
if (!String.IsNullOrEmpty(threadName))
thread.Name = threadName;
// Start the Thread
thread.SetApartmentState(Apartment);
thread.Priority = priority;
thread.IsBackground = IsBackground;
thread.Start(parameter);
// Save the Thread in the Dictionary
if (!String.IsNullOrEmpty(threadName))
_StartedNamedThreads[threadName] = thread;
}
return thread;
}
/// <summary>
/// Starts a thread without Parameters
/// </summary>
/// <param name="method">specifcy a method to invoke</param>
/// <param name="threadName">If you specify a ThreadName, it must be Unique to the Application</param>
/// <param name="Apartment">ApartmentState</param>
/// <param name="IsBackground">Is Background Thread</param>
/// <param name="priority">set thread priority</param>
/// <returns>a thread object if successful, null otherwise</returns>
public static System.Threading.Thread StartThread(ThreadMethod method, string threadName = "", ApartmentState Apartment = ApartmentState.MTA, bool IsBackground = false, ThreadPriority priority = ThreadPriority.Normal)
{
// If a threadName is defined, make sure that it is unique to the system
if (!String.IsNullOrEmpty(threadName) && _StartedNamedThreads.ContainsKey(threadName))
return null;
System.Threading.Thread thread = null;
if (method != null)
{
thread = new System.Threading.Thread(new ThreadStart(method));
if (!String.IsNullOrEmpty(threadName))
thread.Name = threadName;
// Start the Thread
thread.SetApartmentState(Apartment);
thread.Priority = priority;
thread.IsBackground = IsBackground;
thread.Start();
// Save the Thread in the Dictionary
if (!String.IsNullOrEmpty(threadName))
_StartedNamedThreads[threadName] = thread;
}
return thread;
}
/// <summary>
/// Retrieve all Named threads that were started thru here that are still running
/// </summary>
/// <returns>an array of running named threads, null if none</returns>
public static System.Threading.Thread[] GetStartedNamedThreadsThatAreStillRunning()
{
List<System.Threading.Thread> threads = new List<System.Threading.Thread>();
List<string> threadNamesThatAreNoLongerAlive = new List<string>();
// Get Named Alive Threads
foreach (System.Threading.Thread thread in _StartedNamedThreads.Values)
{
if (thread.IsAlive)
threads.Add(thread);
else
threadNamesThatAreNoLongerAlive.Add(thread.Name);
}
// Perform Cleanup
foreach (string threadName in threadNamesThatAreNoLongerAlive)
{
_StartedNamedThreads[threadName] = null;
_StartedNamedThreads.Remove(threadName);
}
return threads.ToArray();
}
#endregion
}
}

143
Thread/TTimer.cs Normal file
View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Windows.Threading;
using WinThread = System.Threading;
namespace Yaulw.Thread
{
/// <remarks>
/// Wrapper class around Timer Object * Multi-Threated *
/// </remarks>
public class TTimer : IDisposable
{
#region Private Members
private Timer _Timer = new Timer();
private bool _disposed = false;
#endregion
#region Construction
/// <summary>
/// Creates a new Multi-threaded System.Timer
/// </summary>
/// <param name="ElapsedHandler">Event Handler for Timer</param>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
public TTimer(ElapsedEventHandler ElapsedHandler, int IntervalMiliseconds = 1000, bool StartEnabled = false)
{
if (ElapsedHandler != null)
{
_Timer = new System.Timers.Timer();
_Timer.Elapsed += ElapsedHandler;
// Set the Interval / start
_Timer.Interval = IntervalMiliseconds;
_Timer.Enabled = StartEnabled;
if (StartEnabled)
_Timer.Start();
// Keep the timer alive
GC.KeepAlive(_Timer);
}
}
/// <summary>
/// Finalizer
/// </summary>
~TTimer()
{
Dispose(true);
}
#endregion
#region Public Methods
/// <summary>
/// Manually Start the Timer
/// </summary>
public void Start()
{
Stop(); // First Stop(), an existing Timer
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Start the Timer at a new Interval
/// </summary>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
public void Start(uint IntervalMiliseconds)
{
Stop(); // First Stop(), an existing Timer
_Timer.Interval = IntervalMiliseconds;
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Start the Timer at a new Interval
/// </summary>
/// <param name="tsInterval">Interval as a TimeSpan</param>
public void Start(TimeSpan tsInterval)
{
Stop(); // First Stop(), an existing Timer
_Timer.Interval = tsInterval.TotalMilliseconds;
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Stop the Timer
/// </summary>
public void Stop()
{
_Timer.Enabled = false;
_Timer.Stop();
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose the Timer Object
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose the Timer Object
/// </summary>
/// <param name="disposing">true, if called from within</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (_Timer != null)
_Timer.Dispose();
}
// Indicate that the instance has been disposed.
_Timer = null;
_disposed = true;
}
}
#endregion
}
}

162
Thread/TTimerDisp.cs Normal file
View File

@@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Windows.Threading;
using WinThread = System.Threading;
namespace Yaulw.Thread
{
/// <remarks>
/// Wrapper class around Timer Object * Uses Dispatcher *
/// </remarks>
public class TTimerDisp : IDisposable
{
#region Private Members
private Timer _Timer = new Timer();
private bool _disposed = false;
private Dispatcher _Dispatcher = null;
private ElapsedEventHandler _DispatchedElapsedEvent = null;
#endregion
#region Construction
/// <summary>
/// Creates a new Multi-threaded System.Timer that uses the Dispatcher to Fire the Event
/// </summary>
/// <param name="ElapsedHandler">Event Handler for Timer</param>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
public TTimerDisp(ElapsedEventHandler ElapsedHandler, int IntervalMiliseconds = 1000, bool StartEnabled = false)
{
if (ElapsedHandler != null)
{
_Timer = new System.Timers.Timer();
// The Primary Dispatcher thread is the thread that called us
_Dispatcher = Dispatcher.CurrentDispatcher;
_DispatchedElapsedEvent = ElapsedHandler;
_Timer.Elapsed += new ElapsedEventHandler(_Timer_Elapsed);
// Set the Interval / start
_Timer.Interval = IntervalMiliseconds;
_Timer.Enabled = StartEnabled;
if (StartEnabled)
_Timer.Start();
// Keep the timer alive
GC.KeepAlive(_Timer);
}
}
/// <summary>
/// Finalizer
/// </summary>
~TTimerDisp()
{
Dispose(true);
}
#endregion
#region Private Helpers
/// <summary>
/// For Dispatching the Event to the Primary Dispatcher Thread
/// </summary>
private void _Timer_Elapsed(object sender, ElapsedEventArgs e)
{
object[] param_s = new object[] { sender, e };
_Dispatcher.Invoke((ElapsedEventHandler)_DispatchedElapsedEvent, param_s);
}
#endregion
#region Public Methods
/// <summary>
/// Manually Start the Timer
/// </summary>
public void Start()
{
Stop(); // First Stop(), an existing Timer
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Start the Timer at a new Interval
/// </summary>
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
public void Start(uint IntervalMiliseconds)
{
Stop(); // First Stop(), an existing Timer
_Timer.Interval = IntervalMiliseconds;
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Start the Timer at a new Interval
/// </summary>
/// <param name="tsInterval">Interval as a TimeSpan</param>
public void Start(TimeSpan tsInterval)
{
Stop(); // First Stop(), an existing Timer
_Timer.Interval = tsInterval.TotalMilliseconds;
_Timer.Enabled = true;
_Timer.Start();
}
/// <summary>
/// Manually Stop the Timer
/// </summary>
public void Stop()
{
_Timer.Enabled = false;
_Timer.Stop();
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose the Timer Object
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose the Timer Object
/// </summary>
/// <param name="disposing">true, if called from within</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (_Timer != null)
_Timer.Dispose();
}
// Indicate that the instance has been disposed.
_Timer = null;
_disposed = true;
}
}
#endregion
}
}

45
Tools/Convert.cs Normal file
View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Tools
{
/// <remarks>
/// Common Conversion Operations
/// </remarks>
public static class Convert
{
/// <summary>
/// Convert a a String to a UTF Byte Array
/// </summary>
/// <param name="str">string to convert</param>
/// <returns>a Byte Array from a String</returns>
public static byte[] StrToByteArrayUTF(string str)
{
if (!String.IsNullOrEmpty(str))
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetBytes(str);
}
return null;
}
/// <summary>
/// Convert a a String to an ASCII Byte Array
/// </summary>
/// <param name="str">string to convert</param>
/// <returns>a Byte Array from a String</returns>
public static byte[] StrToByteArrayAscii(string str)
{
if (!String.IsNullOrEmpty(str))
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
return null;
}
}
}

143
Tools/EnumTool.cs Normal file
View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Tools
{
/// <remarks>
/// Common Operations on Enumerations
/// </remarks>
public static class EnumTool
{
#region Common Operations
/// <summary>
/// Turns an Enum to a String (Replacing _ with ' ')
/// </summary>
/// <param name="_enum">an Enum which could possibly contain an '_'</param>
/// <returns>a ' ' spaced String of Enum</returns>
public static string Enum_ToString(Enum _enum)
{
return _enum.ToString().Replace('_', ' ');
}
/// <summary>
/// Using the '__' in the Enum Name allows to embed Categories in the Name
/// </summary>
/// <param name="_enum">an Enum with '__'</param>
/// <param name="Category">The String Value before the '__', also replacing '_' with ' '</param>
/// <param name="Key">The String Value after the '__', also replacing '_' with ' '</param>
public static void Enum_ToCategoryNKey(Enum _enum, out string Category, out string Key)
{
Category = String.Empty;
Key = String.Empty;
if (!Enum_HasCategoryNKey(_enum))
throw new ArgumentException("_enum must contain a __ with category and key values");
string _enumStr = _enum.ToString();
int nIndex = _enumStr.IndexOf("__");
// Assign out the Retrived Values
Category = _enumStr.Substring(0, nIndex).Replace('_', ' ');
Key = _enumStr.Substring(nIndex + 2).Replace('_', ' ');
}
#endregion
#region HasCategoryNKey
/// <summary>
/// Determines if the Passed in Enum has both a Category and Key
/// </summary>
/// <param name="_enum">an Enum with '__'</param>
/// <returns>true if '__' is present with both a category and key value</returns>
public static bool Enum_HasCategoryNKey(Enum _enum)
{
// Check to see there is only one __
string _enumStr = _enum.ToString();
int nIndexFirst = _enumStr.IndexOf("__");
int nIndexLast = _enumStr.LastIndexOf("__");
if (nIndexFirst == nIndexLast)
{
// Check to see that there are values infront and behind the __
if (nIndexFirst != 0 && (nIndexLast < (_enumStr.Length - 1)))
return true;
}
return false;
}
/// <summary>
/// Determines if all the Enums of the Passed in Enum Type have both a Category and Key
/// </summary>
/// <param name="_enum">an Enum Type that has all enums with '__'</param>
/// <returns>true if '__' is present with both a category and key value on all enums</returns>
public static bool EnumType_HasCategoryNKey(Type _enumType)
{
if (_enumType.IsEnum)
{
foreach (string enumName in Enum.GetNames(_enumType))
{
bool bIsValid = Enum_HasCategoryNKey((Enum)Enum.Parse(_enumType, enumName));
if (!bIsValid)
return false;
}
return true;
}
return false;
}
#endregion
#region Category N' Key Traversals
/// <summary>
/// Retrieves all the Categories of an Enum
/// </summary>
/// <param name="_enum">an Enum Type that has all enums with '__'</param>
/// <returns>An Array of all unique Categories, '_' replaced with ' ', or null if error occured</returns>
public static string[] EnumType_GetCategories(Type _enumType)
{
if (_enumType.IsEnum && EnumType_HasCategoryNKey(_enumType))
{
List<String> retVal = new List<String>();
foreach (string enumName in Enum.GetNames(_enumType))
{
string Category;
string Key;
Enum_ToCategoryNKey((Enum)Enum.Parse(_enumType, enumName), out Category, out Key);
if(!retVal.Contains(Category))
retVal.Add(Category);
}
return retVal.ToArray();
}
return null;
}
/// <summary>
/// Retrieves all the Keys of an Enum for a specified Category
/// </summary>
/// <param name="_enum">an Enum Type that has all enums with '__'</param>
/// <returns>An Array of all unique Keys, '_' replaced with ' ', or null if error occured</returns>
public static string[] EnumType_GetKeys(Type _enumType, string Category)
{
if (_enumType.IsEnum && EnumType_HasCategoryNKey(_enumType))
{
List<String> retVal = new List<String>();
foreach (string enumName in Enum.GetNames(_enumType))
{
string CategoryTemp;
string Key;
Enum_ToCategoryNKey((Enum)Enum.Parse(_enumType, enumName), out CategoryTemp, out Key);
if (String.Compare(Category, CategoryTemp, true) == 0)
retVal.Add(Key);
}
return retVal.ToArray();
}
return null;
}
#endregion
}
}

269
Tools/ObjTool.cs Normal file
View File

@@ -0,0 +1,269 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Tools
{
/// <remarks>
/// Useful Utilities around objects
/// </remarks>
public static class ObjTool
{
/// <summary>
/// Returns true if passed in object is valid and is not empty
/// </summary>
/// <param name="oToValidate">an object to validate</param>
/// <returns>true if valid, false otherwise</returns>
public static bool IsNotNullAndNotEmpty(object oToValidate)
{
if ((oToValidate != null) && (oToValidate.ToString() != String.Empty))
return true;
else
return false;
}
/// <summary>
/// Use this to just check if the object can be converted to a string
/// via ConvertObjToString(). If false, this is most likely an object type that shouldn't be converted to a string.
/// </summary>
/// <typeparam name="T">Can be Any type</typeparam>
/// <param name="objToCheckConvert">an object of type T to check if String Convertible</param>
/// <returns>true, if the object passed in a String Convertible type like string, bool, int32, double, decimal, etc..., false otherwise</returns>
public static bool IsOfTypeConvertibleToString<T>(T objToCheckConvert)
{
bool retVal = false;
T objToConvert = objToCheckConvert;
// Check if String Convertible
if (objToConvert is System.Char)
{
retVal = true;
}
else if (objToConvert is System.String)
{
retVal = true;
}
else if (objToConvert is System.Decimal)
{
retVal = true;
}
else if (objToConvert is System.Int32)
{
retVal = true;
}
else if (objToConvert is System.Int64)
{
retVal = true;
}
else if (objToConvert is System.Single)
{
retVal = true;
}
else if (objToConvert is System.Double)
{
retVal = true;
}
else if (objToConvert is System.Boolean)
{
retVal = true;
}
else if (objToConvert is System.DateTime)
{
retVal = true;
}
#if NET4
else if (objToConvert is System.Guid) // Only works in .Net 4.0
{
retVal = true;
}
#endif
else if (objToConvert is System.IntPtr)
{
retVal = true;
}
else if (objToConvert is System.UInt32)
{
retVal = true;
}
else if (objToConvert is System.UInt64)
{
retVal = true;
}
return retVal;
}
/// <summary>
/// Convert a string to an Object of Type T
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="strToConvert">String Value to Convert</param>
/// <returns>an converted Object of Type t, or T Default if error occured</returns>
public static T ConvertStringToObj<T>(string strToConvert)
{
// Create a Default Type T
T retVal = default(T);
try
{
#region Conversion
if (retVal is System.Char)
{
retVal = (T)((object)strToConvert[0]);
}
else if (retVal is System.String)
{
retVal = (T)((object)strToConvert);
}
else if (retVal is System.Decimal)
{
retVal = (T)((object)Decimal.Parse(strToConvert));
}
else if (retVal is System.Int32)
{
retVal = (T)((object)Int32.Parse(strToConvert));
}
else if (retVal is System.Int64)
{
retVal = (T)((object)Int64.Parse(strToConvert));
}
else if (retVal is System.Single)
{
retVal = (T)((object)Single.Parse(strToConvert));
}
else if (retVal is System.Double)
{
retVal = (T)((object)Double.Parse(strToConvert));
}
else if (retVal is System.Boolean)
{
retVal = (T)((object)Boolean.Parse(strToConvert));
}
else if (retVal is System.DateTime)
{
retVal = (T)((object)DateTime.Parse(strToConvert));
}
#if NET4
else if (retVal is System.Guid) // Works in .Net 4.0 and up
{
retVal = (T)((object)Guid.Parse(strToConvert));
}
#endif
else if (retVal is System.IntPtr)
{
if (IntPtr.Size <= 4)
{
Int32 i = Int32.Parse(strToConvert);
retVal = (T)((object)new IntPtr(i));
}
else
{
Int64 i = Int64.Parse(strToConvert);
retVal = (T)((object)new IntPtr(i));
}
}
else if (retVal is System.UInt32)
{
retVal = (T)((object)UInt32.Parse(strToConvert));
}
else if (retVal is System.UInt64)
{
retVal = (T)((object)UInt64.Parse(strToConvert));
}
else
{
retVal = (T)((object)(strToConvert));
}
#endregion
}
catch (Exception e) { string Message = e.Message; /* ignore */ }
// return T
return retVal;
}
/// <summary>
/// Convert an object of type t to a String
/// </summary>
/// <typeparam name="T">Should be a System Type like string, bool, int32, double, decimal, etc...</typeparam>
/// <param name="objToConvert">Object Value to Convert</param>
/// <returns>a string that contains the value of the Object</returns>
public static string ConvertObjToString<T>(T objToConvert)
{
String retVal = String.Empty;
try
{
#region Conversion
if (objToConvert is System.Char)
{
retVal = ((Char)((object)objToConvert)).ToString();
}
else if (objToConvert is System.String)
{
retVal = ((String)((object)objToConvert)).ToString();
}
else if (objToConvert is System.Decimal)
{
retVal = ((Decimal)((object)objToConvert)).ToString();
}
else if (objToConvert is System.Int32)
{
retVal = ((Int32)((object)objToConvert)).ToString();
}
else if (objToConvert is System.Int64)
{
retVal = ((Int64)((object)objToConvert)).ToString();
}
else if (objToConvert is System.Single)
{
retVal = ((Single)((object)objToConvert)).ToString();
}
else if (objToConvert is System.Double)
{
retVal = ((Double)((object)objToConvert)).ToString();
}
else if (objToConvert is System.Boolean)
{
retVal = ((Boolean)((object)objToConvert)).ToString();
}
else if (objToConvert is System.DateTime)
{
retVal = ((DateTime)((object)objToConvert)).ToString();
}
#if NET4
else if (objToConvert is System.Guid)
{
retVal = ((Guid)((object)objToConvert)).ToString();
}
#endif
else if (objToConvert is System.IntPtr)
{
retVal = ((IntPtr)((object)objToConvert)).ToString();
}
else if (objToConvert is System.UInt32)
{
retVal = ((UInt32)((object)objToConvert)).ToString();
}
else if (objToConvert is System.UInt64)
{
retVal = ((UInt64)((object)objToConvert)).ToString();
}
else
{
retVal = ((object)objToConvert).ToString();
}
#endregion
}
catch (Exception) { /* ignore */ }
// return T
return retVal;
}
}
}

259
Tools/PathNaming.cs Normal file
View File

@@ -0,0 +1,259 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Yaulw.Tools
{
/// <remarks>
/// Tools For File/Directory Paths
/// </remarks>
public static class PathNaming
{
/// <summary>
/// Get the Root Path for a given path string
/// </summary>
/// <param name="path">path</param>
/// <returns>the root folder, with '\'</returns>
public static string GetPathRoot(string path)
{
if(!String.IsNullOrEmpty(path))
return PathEndsWithSlash(System.IO.Path.GetPathRoot(path));
return "";
}
/// <summary>
/// Does Path contain file information
/// </summary>
/// <returns>returns true if the specified path information contains file information</returns>
public static bool PathContainsFile(string path)
{
if (!String.IsNullOrEmpty(path) && (path.LastIndexOf('.') > path.LastIndexOf('\\')))
return true;
return false;
}
/// <summary>
/// Makes sure that the specified path begins with a '\'
/// </summary>
/// <returns>a path string that begins with \</returns>
public static string PathBeginsWithSlash(string path)
{
if (!String.IsNullOrEmpty(path) && (path[0] != '\\'))
return '\\' + path;
return path;
}
/// <summary>
/// Makes sure that the specified path does NOT begin with a '\'
/// </summary>
/// <returns>a path string that does NOT begin with \</returns>
public static string PathBeginsWithNoSlash(string path)
{
if (!String.IsNullOrEmpty(path) && (path[0] == '\\'))
return path.Substring(1);
return path;
}
/// <summary>
/// Makes sure that the specified path ends with a '\'
/// </summary>
/// <returns>a path string that ends with \</returns>
public static string PathEndsWithSlash(string path)
{
if (!String.IsNullOrEmpty(path) && (path[path.Length - 1] != '\\'))
return path + '\\';
return path;
}
/// <summary>
/// Makes sure that the specified path does NOT end with a '\'
/// </summary>
/// <returns>a path string that does NOT end with \</returns>
public static string PathEndsWithNoSlash(string path)
{
if (!String.IsNullOrEmpty(path) && (path[path.Length - 1] == '\\'))
return path.Substring(0, path.Length - 1);
return path;
}
/// <summary>
/// Returns True if the fileName is valid * Filename chars are More restrictive than Path * should always use this
/// </summary>
/// <param name="FileName">filename to check for</param>
/// <returns>true, if valid, false otherwise</returns>
public static bool FileNameIsValid(string FileName)
{
if (!String.IsNullOrEmpty(FileName))
{
// stripe out the filename, if possible, if not, just use what is
// passed into us
string file = Path.GetFileName(FileName);
if (!String.IsNullOrEmpty(file))
FileName = file;
char[] invalidChars = Path.GetInvalidFileNameChars();
foreach (char c in invalidChars)
{
if (FileName.Contains(c))
return false;
}
return true;
}
return false;
}
/// <summary>
/// Returns True if the Directory Path is valid * Path chars are not as restrictive as File * should always use File Chars (better safe than sorry)
/// Use FileNameIsValid()
/// </summary>
/// <param name="DirectoryPath">DirectoryPath to check for</param>
/// <returns>true, if valid, false otherwise</returns>
public static bool IsDirectoryPathValid(string DirectoryPath)
{
if (!String.IsNullOrEmpty(DirectoryPath))
{
// stripe the trailing '\\', if possible, if not, just use what is
// passed into us
string path = Path.GetDirectoryName(DirectoryPath);
if (!String.IsNullOrEmpty(path))
DirectoryPath = path;
// FileName Char restrictions contain everything we need,
// except for a path we want to allow '\\'
char[] invalidChars = Path.GetInvalidFileNameChars();
foreach (char c in invalidChars)
{
// allow '\\' for paths
if (c != '\\' && DirectoryPath.Contains(c))
return false;
}
return true;
}
return false;
}
/// <summary>
/// return a valid directory path, a path that is invalid and contains invalid
/// characters is automatically converted, (illegal characters are skipped)
/// </summary>
/// <param name="DirectoryPath">DirectoryPath to change</param>
/// <returns>the 'corrected' path string</returns>
public static string MakeDirectoryPathValid(string DirectoryPath)
{
return MakeDirectoryPathValid(DirectoryPath, String.Empty);
}
/// <summary>
/// return a valid directory path, a path that is invalid and contains invalid
/// characters is automatically converted, (illegal characters are skipped)
/// </summary>
/// <param name="DirectoryPath">DirectoryPath to change</param>
/// <param name="replacementStr">the string to put in place instead of the invalid char found,
/// it itself can't be an invalid char</param>
/// <returns>the 'corrected' path string</returns>
public static string MakeDirectoryPathValid(string DirectoryPath, string replacementStr)
{
if(!String.IsNullOrEmpty(DirectoryPath))
{
// stripe the trailing '\\', if possible, if not, just use what is
// passed into us
string path = Path.GetDirectoryName(DirectoryPath);
if (!String.IsNullOrEmpty(path))
DirectoryPath = path;
// FileName Char restrictions contain everything we need,
// except for a path we want to allow '\\'
char[] invalidChars = Path.GetInvalidFileNameChars();
// Make sure replacementStr is valid also, otherwise it somewhat defeats the purpose
// of this whole function
string strToUseForReplacement = "";
bool replacementStrIsValid = false;
if (replacementStr != null)
{
replacementStrIsValid = true;
if (replacementStr != "")
{
foreach (char c in replacementStr)
{
invalidChars.Contains(c);
replacementStrIsValid = false;
break;
}
}
}
if (replacementStrIsValid)
strToUseForReplacement = replacementStr;
// Construct new String Path
StringBuilder sb = new StringBuilder();
foreach (char c in DirectoryPath)
{
// allow '\\' for paths
if (c != '\\' && invalidChars.Contains(c))
{
sb.Append(strToUseForReplacement);
}
else
{
sb.Append(c);
}
}
return sb.ToString();
}
return DirectoryPath;
}
/// <summary>
/// Retrieve the last directory name from a path, can be a UNC path like \\{server}\Directory
/// or a file and system path like C:\{directory}\{directory}, will always return the name of the
/// last directory in the path. if it is not a path, i.e just a name is passed in without '\'s then
/// it will just stripe out all '\' that maybe there and return the name
/// </summary>
/// <param name="DirectoryPath"></param>
/// <returns>the name of the last directory in the path</returns>
public static string RetrieveLastDirectoryNameInPath(string DirectoryPath)
{
if (!String.IsNullOrEmpty(DirectoryPath))
{
// Find the last folder and return that information
// This is what this function was created for
string dp = Path.GetDirectoryName(DirectoryPath);
int nLast = dp.LastIndexOf('\\');
if (nLast != -1 && dp.Length > 3)
{
dp = dp.Substring(nLast + 1);
return dp;
}
// Return what was passed into us, probably doesn't have a '\\',
// but it could be that it just has one. like someone passed in \\{server},
// then we'll just return the {server}, if someone passes in c:\directory, then,
// we should pass back just the directory
if (DirectoryPath.Length > 3 && DirectoryPath[1] == ':')
{
return DirectoryPath.Substring(3);
}
else
{
// try finding the last \\, again without using GetDirectoryName which
// stripes it, return the last stuff found, otherwise just return what was passed to us
nLast = DirectoryPath.LastIndexOf('\\');
if (nLast != -1 && DirectoryPath.Length > 3)
{
return DirectoryPath.Substring(nLast + 1);
}
else
{
return DirectoryPath;
}
}
}
return String.Empty;
}
}
}

165
Tools/StringTool.cs Normal file
View File

@@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Tools
{
/// <summary>
/// Useful String Operations
/// </summary>
public static class StringTool
{
/// <summary>
/// Searches for the 'value' occurences that occur in 'str'
/// </summary>
/// <param name="value">string to search occurences for</param>
/// <param name="str">string to search in</param>
/// <param name="bIgnoreCase">true to ignore case, false otherwise</param>
/// <returns>the number of occurences of 'value' in 'str', 0 for none</returns>
public static uint NumberOfSpecStringFoundInString(string value, string str, bool bIgnoreCase = false)
{
uint nCount = 0;
if (!String.IsNullOrEmpty(str))
{
int nIndex = 0;
StringComparison comparison = bIgnoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture;
do
{
nIndex = str.IndexOf(value, nIndex, comparison);
if(nIndex != -1)
++nCount;
} while (nIndex != -1);
}
return nCount;
}
/// <summary>
/// Check to see if string starts with a letter
/// </summary>
/// <param name="str">string to check</param>
/// <returns>true if string starts with a letter</returns>
public static bool StringStartsWithLetter(string str)
{
if (!String.IsNullOrEmpty(str))
return char.IsLetter(str[0]);
return false;
}
/// <summary>
/// Check to see if string ends with a letter
/// </summary>
/// <param name="str">string to check</param>
/// <returns>true if string ends with a letter</returns>
public static bool StringEndsWithLetter(string str)
{
if (!String.IsNullOrEmpty(str))
return char.IsLetter(str[str.Length - 1]);
return false;
}
/// <summary>
/// Returns the last word of a string (string must end with a letter)
/// </summary>
/// <param name="str">string to go thru</param>
/// <returns>the last word of a string</returns>
public static string StringFetchLastWord(string str)
{
if (!String.IsNullOrEmpty(str) && StringEndsWithLetter(str))
{
// Find the last word
StringBuilder sb = new StringBuilder();
for (int i = str.Length - 1; i >= 0; --i)
{
if (char.IsLetter(str[i]))
sb.Append(str[i]);
else
break;
}
// Reverse the String
string strRet = sb.ToString();
#if NET4
sb.Clear();
#else
sb = new StringBuilder();
#endif
for (int i = strRet.Length - 1; i >=0; --i)
sb.Append(strRet[i]);
// return the string
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Returns the first word of a string (string must start with a letter)
/// </summary>
/// <param name="str">string to go thru</param>
/// <returns>the first word of a string</returns>
public static string StringFetchFirstWord(string str)
{
if (!String.IsNullOrEmpty(str) && StringStartsWithLetter(str))
{
// Find the last word
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.Length; ++i)
{
if (char.IsLetter(str[i]))
sb.Append(str[i]);
else
break;
}
// return the string
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Stripes the last word from the referenced string (string must end with a letter)
/// </summary>
/// <param name="str">last word stripped from string</param>
public static void StringStripeLastWord(ref string str)
{
if (!String.IsNullOrEmpty(str) && StringEndsWithLetter(str))
{
// Find the last word
int i = 0;
for (i = str.Length - 1; i >= 0; --i)
{
if (!char.IsLetter(str[i]))
break;
}
// Return string without last word
str = str.Substring(0, i + 1);
}
}
/// <summary>
/// Stripes the first word from the referenced string (string must start with a letter)
/// </summary>
/// <param name="str">first word stripped from string</param>
public static void StringStripeFirstWord(ref string str)
{
if (!String.IsNullOrEmpty(str) && StringStartsWithLetter(str))
{
// Find the last word
int i = 0;
for (i = 0; i < str.Length; ++i)
{
if (!char.IsLetter(str[i]))
break;
}
// Return string without first word
str = str.Substring(i);
}
}
}
}

319
WPF/KeepHidden.cs Normal file
View File

@@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
using System.Timers;
using Yaulw.Thread;
namespace Yaulw.WPF
{
/// <remarks>
/// Class used to keep WPF Windows Hidden permanently.
/// This should ideally be called in the Constructor of a window you want to keep hidden.
/// <example>
/// <code>
/// private static KeepHidden _HiddenWindow = null;
/// public HiddenMainWindow()
/// {
/// // * Force this window to remain hidden indefinitly*
/// _HiddenWindow = new KeepHidden(this);
/// }
/// </code>
/// </example>
/// </remarks>
public class KeepHidden
{
#region Private Statics
// Static Map of All our Hidden Windows
private static Dictionary<IntPtr, Window> s_hWndToWindowMap = new Dictionary<IntPtr, Window>();
private static List<Window> s_WindowList = new List<Window>();
private Window _wpfWindow = null;
private object _lockObj = new Object();
#endregion
#region Public Properties
/// <summary>
/// Get the WPF Object That is bound to this Keep Hidden Instance
/// </summary>
public Window wpfWindow { get { return _wpfWindow; } }
/// <summary>
/// Get the HWND Handle to the WPF Object bound to this Keep Hidden Instance
/// </summary>
public IntPtr hwndWindow
{
get
{
if (_wpfWindow != null)
{
WindowInteropHelper interop = new WindowInteropHelper(_wpfWindow);
return interop.Handle;
}
return IntPtr.Zero;
}
}
#endregion
#region Construction
/// <summary>
/// When Passing in a Wpf Window in this Construction, it will ensure that
/// This Window will remain hidden during it's life span. If the Window is Not Loaded
/// yet, call KeepHidden's Show() method to show it, after construction.
/// </summary>
/// <param name="wpfWindow">a WPF Window Object that you want to keep Hidden</param>
public KeepHidden(Window wpfWindow)
{
if (wpfWindow != null && !wpfWindow.IsLoaded)
{
// Assign the Load Event Handler we care about
wpfWindow.Loaded += new RoutedEventHandler(wpfWindow_Loaded);
}
else if (wpfWindow != null && wpfWindow.IsLoaded)
{
// Call the Loaded Event Handler Directly
wpfWindow_Loaded((object)wpfWindow, null);
}
else
throw new ArgumentException("Please pass valid WPF Window Object");
// Make sure we aren't already tracking this window
if (s_WindowList.Contains(wpfWindow))
throw new ArgumentException("WPF Window Object already Kept Hidden");
// Assign remaining stuff
wpfWindow.Closing += new System.ComponentModel.CancelEventHandler(wpfWindow_Closing);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
_wpfWindow = wpfWindow;
// Add to WPF Window List
s_WindowList.Add(wpfWindow);
// Call this upon construction ~Done Way before Show() get's called
HideWPFWindow(_wpfWindow);
}
#endregion
#region Public Methods
/// <summary>
/// Call this to execute a Show() call on the WPF Window that you want to Keep Hidden
/// </summary>
public void Show()
{
if (_wpfWindow != null && !_wpfWindow.IsLoaded)
{
lock (_lockObj)
{
// Make sure it can't be seen or interacted with
HideWPFWindow(_wpfWindow);
// Show it
_wpfWindow.Show();
// Again... make sure...
HideWPFWindow(_wpfWindow);
// Hide it immediatly, make sure it can't be interacted with
_wpfWindow.Hide();
}
}
}
/// <summary>
/// Call this to execute a Show() call on the WPF Window that you want to Keep Hidden
/// ~However, it will delay call the show allowing the hidden window's constructor to finish
/// </summary>
/// <param name="nDelayInMilliseconds">Milliseconds to delay show the HiddenWindow (at least 250 recommended)</param>
public void Show(uint nDelayInMilliseconds)
{
// Calling Show() directly in the Constructor causes a .Net Run-time Crash
// upon first launch only. Calling it .5 seconds later does the trick of avoiding that error,
// because by then the object is fully constructed
ElapsedEventHandler DelayShowHiddenWindow = delegate(object sender, ElapsedEventArgs e)
{
Timer timer = (Timer)sender;
timer.Stop();
// * Show the Hidden Window *
Show();
timer.Dispose();
timer = null;
};
TTimerDisp timerDelayShowHiddenWindow = new TTimerDisp(DelayShowHiddenWindow, (int) nDelayInMilliseconds, true);
}
/// <summary>
/// Call this to execute a Close() call on the WPF Window that you previously had hidden
/// ~Should only call this when you are done with the Keep Hidden Object
/// </summary>
public void Close()
{
if (_wpfWindow != null && _wpfWindow.IsLoaded)
{
_wpfWindow.Close();
_wpfWindow = null;
}
}
#endregion
#region Public Static Methods
/// <summary>
/// Call this function to determine if the passed in Window is a Hidden Window Object * Tracked by KeepHidden *
/// </summary>
/// <param name="_wpfWindow">pass in a wpf window object to check</param>
/// <returns></returns>
public static bool IsHiddenWindow(Window _wpfWindow)
{
if (_wpfWindow != null)
{
bool bIsFound = s_WindowList.Contains(_wpfWindow);
return bIsFound;
}
return false;
}
#endregion
#region Private Keep Hidden Event Handlers
/// <summary>
/// Called by the WPFWindow's OnLoad Event
/// </summary>
private void wpfWindow_Loaded(object sender, RoutedEventArgs e)
{
lock (_lockObj)
{
Window wpfWindow = (Window)sender;
HideWPFWindow(wpfWindow);
// Add Window Source Message Hook * We'll track the hWnd for the Message Hook
// vie s_hWndToWindowMap
WindowInteropHelper interop = new WindowInteropHelper(wpfWindow);
s_hWndToWindowMap[interop.Handle] = wpfWindow;
HwndSource source = HwndSource.FromHwnd(interop.Handle);
source.AddHook(new HwndSourceHook(MessageHook));
}
}
/// <summary>
/// Called by the WPFWindow's Closing Event
/// </summary>
private void wpfWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
lock (_lockObj)
{
// Delete from the hWndMap, so Message Hook
// Stops processing messages
Window wpfWindow = (Window)sender;
if (s_hWndToWindowMap.ContainsValue(wpfWindow))
{
foreach (IntPtr hWnd in s_hWndToWindowMap.Keys)
{
if (s_hWndToWindowMap[hWnd] == wpfWindow)
{
s_hWndToWindowMap.Remove(hWnd);
break;
}
}
}
// * Imp * Delete internal wpfWindow Reference,
// but DON'T Delete from the s_WindowList. Caller could still call IsHiddenWindow(),
// and we MUST return true if it is
_wpfWindow = null;
}
}
/// <summary>
/// Called by the Process Exiting * We want this to happen last *
/// This allows all unload events for each window to happen first
/// </summary>
void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
// Make sure to clear all windows
s_hWndToWindowMap.Clear();
// Make sure to clear all windows
s_WindowList.Clear();
}
/// <summary>
/// This Message Hook is for the WpfWindow to absolutely ensure that it remains Hidden.
/// We want to make sure that it is never displayed *It can occur that explorer.exe can show it, without this hook*
/// ~i.e. when explorer.exe crashes, and get's restarted, it can cause inconsitencies
/// </summary>
private IntPtr MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// Get the Proper WPF Object and make sure it is Hidden
if (s_hWndToWindowMap.ContainsKey(hwnd))
{
Window wpfWindow = s_hWndToWindowMap[hwnd];
if (wpfWindow != null)
HideWPFWindow(wpfWindow);
}
handled = false;
return System.IntPtr.Zero;
}
#endregion
#region Private Hide Window Functionality
/// <summary>
/// * Core * 'Hiding' Function. Makes sure that the Window is and
/// stays hidden.
/// </summary>
/// <remarks>
/// Height="2" Width="2" AllowsTransparency="True" Background="{x:Null}" WindowStyle="None" WindowStartupLocation="Manual" WindowState="Normal" ResizeMode="NoResize" Foreground="{x:Null}" ShowInTaskbar="False" ShowActivated="False" Left="0" Top="0" MaxWidth="2" MaxHeight="2" MinHeight="2" MinWidth="2" Visibility="Hidden" Opacity="0" IsHitTestVisible="False" IsTabStop="False" Focusable="False" IsEnabled="False"
/// </remarks>
/// <param name="wpfWindow">a WPF window object</param>
private void HideWPFWindow(Window wpfWindow)
{
// Force a tiny Window in top-left corner
wpfWindow.Width = 2;
wpfWindow.Height = 2;
wpfWindow.MinWidth = 2;
wpfWindow.MinHeight = 2;
wpfWindow.MaxWidth = 2;
wpfWindow.MaxHeight = 2;
wpfWindow.Top = 0;
wpfWindow.Left = 0;
// Force transparency
if (!wpfWindow.IsLoaded) // must not be already loaded
wpfWindow.AllowsTransparency = true;
wpfWindow.Background = null;
wpfWindow.Foreground = null;
// Force no user interaction
wpfWindow.WindowStartupLocation = WindowStartupLocation.Manual;
wpfWindow.WindowState = WindowState.Normal;
wpfWindow.ResizeMode = ResizeMode.NoResize;
wpfWindow.ShowInTaskbar = false;
wpfWindow.ShowActivated = false;
wpfWindow.Visibility = Visibility.Hidden;
wpfWindow.IsHitTestVisible = false;
wpfWindow.IsTabStop = false;
wpfWindow.Focusable = false;
// Force Opacity
wpfWindow.WindowStyle = WindowStyle.None;
wpfWindow.Opacity = 0.0;
}
#endregion
}
}

156
WPF/Snippets.cs Normal file
View File

@@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Interop;
namespace Yaulw.WPF
{
/// <remarks>
/// Useful WPF Snippets
/// </remarks>
static public class Snippets
{
/// <summary>
/// Useful to create a simple wrapping tooltip for a wpf control
/// </summary>
/// <param name="strToolTipContent"></param>
/// <param name="height">Set to 0 to leave default, else set to 0> to define max height</param>
/// <param name="width">Set to 0 to leave default, else set to 0> to define max width</param>
/// <returns>a ToolTip Object to assign to a control</returns>
public static ToolTip CreateNewStringToolTip(string strToolTipContent, int height, int width)
{
// Create the TextBlock
TextBlock tx = new TextBlock();
if (height > 0)
tx.Height = height;
if (width > 0)
tx.Width = width;
tx.TextWrapping = TextWrapping.Wrap;
tx.Text = strToolTipContent;
// Create the ToolTip with the TextBlock inside
ToolTip tt = new ToolTip();
tt.Content = strToolTipContent;
return tt;
}
/// <summary>
/// Useful if you want to know if the Mouse cursor is over the specified Wpf Window
/// (Uses windowsforms to do the calculations)
/// </summary>
/// <returns>true if the mouse cursor is over the specified form window, false otherwise</returns>
public static bool IsMouseCursorOverWPFormWindow(Window wpfWindow)
{
if (wpfWindow != null)
{
// Get the Point location of the mouse cursor
System.Drawing.Point point = System.Windows.Forms.Cursor.Position;
// Get the rect for the Navigation Form
Point wpfFormLeftTopPoint = new Point(wpfWindow.Left, wpfWindow.Top);
Size wpfFormSize = new Size(wpfWindow.Width, wpfWindow.Height);
Rect rect = new Rect(wpfFormLeftTopPoint, wpfFormSize);
// Return if the Mouse is over the Navigation Form
return (rect.Contains((double)point.X, (double)point.Y));
}
return false;
}
/// <summary>
/// For Dynamically Creating Text ComboBox Items
/// </summary>
/// <param name="strContent">Text Content to Display</param>
/// <param name="tag">object to tag to the menu item</param>
/// <returns></returns>
public static ComboBoxItem CreateAComboBoxItem(string strContent, object tag)
{
if (!String.IsNullOrEmpty(strContent) && (tag != null))
{
ComboBoxItem item = new ComboBoxItem();
item.Content = strContent;
item.Tag = tag;
return item;
}
return null;
}
/// <summary>
/// For dynamically creating Image sources, this function helps you to create an image out of
/// a Resource Uri. You can then assign this image to a 'Source' property on an image wpf object
/// </summary>
/// <param name="strRelativeResourceUri">a valid relative Resource Uri String to an image</param>
/// <param name="ImageHeight">the output image's desired height</param>
/// <param name="ImageWidth">the output image's desired width</param>
/// <returns></returns>
public static Image CreateWPFImageFromRelativeResourceUri(string strRelativeResourceUri, int ImageHeight, int ImageWidth)
{
if (!String.IsNullOrEmpty(strRelativeResourceUri))
{
Image myImage = new Image();
BitmapImage image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(strRelativeResourceUri, UriKind.Relative);
image.EndInit();
myImage.Stretch = Stretch.Fill;
myImage.Height = ImageHeight;
myImage.Width = ImageWidth;
myImage.Source = image;
return myImage;
}
return null;
}
/// <summary>
/// Uses the InteropHelper to get the Handle of a WPF Window
/// </summary>
/// <param name="window">a WPF Window</param>
/// <returns>an hWnd for the specified WPF Window</returns>
public static IntPtr GetHandleForWPFWindow(Window window)
{
WindowInteropHelper InteropHelper = new WindowInteropHelper(window);
if (InteropHelper.Handle != IntPtr.Zero)
return InteropHelper.Handle;
#if NET4
else
return InteropHelper.EnsureHandle();
#else
else
return IntPtr.Zero;
#endif
}
/// <summary>
/// Uses the InteropHelper to set the Owner Property of a WPF Window
/// </summary>
/// <param name="window">a WPF Window</param>
/// <param name="hOwnerWnd">Owner hWnd Handle to set for WPF Window</param>
public static void SetOwnerForWPFWindow(Window window, IntPtr hOwnerWnd)
{
WindowInteropHelper InteropHelper = new WindowInteropHelper(window);
InteropHelper.Owner = hOwnerWnd;
}
/// <summary>
/// Adds the Specified Message Hook the the specified WPF Window.
/// Ensures that the WPF Window exists (must be loaded with valid hWnd).
/// </summary>
/// <param name="window">a WPF Window</param>
/// <param name="hook">a message hook function</param>
public static void SetMessageHookForWPFWindow(Window window, HwndSourceHook hook)
{
WindowInteropHelper interop = new WindowInteropHelper(window);
#if NET4
HwndSource source = HwndSource.FromHwnd(interop.EnsureHandle());
#else
HwndSource source = HwndSource.FromHwnd(interop.Handle);
#endif
source.AddHook(hook);
}
}
}

232
WPF/WPFWindowManager.cs Normal file
View File

@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using Yaulw.Thread;
using System.Windows;
using Yaulw.Other;
using System.Collections;
using System.Windows.Interop;
namespace Yaulw.WPF
{
/// <summary>
/// Responsible for Managing WPFWindows
/// </summary>
public class WPFWindowManager : WindowManager
{
#region Construction
/// <summary>
/// WPFWindow Manager Contructor
/// </summary>
/// <param name="dispatcher">Thread Dispatcher Object</param>
/// <param name="windowTypes">Window Types this WindowManager is managing</param>
/// <param name="PerformanceLoad">true, to load performance enabled windows upon construction</param>
public WPFWindowManager(Dispatcher dispatcher, WindowType[] windowTypes, bool PerformanceLoad)
: base(dispatcher, windowTypes, PerformanceLoad)
{
// Here i can load Show/hide all windows that are performance loaded * To further load stuff WPF related *
if (PerformanceLoad)
{
foreach (WindowType type in windowTypes)
{
List<object> objects = GetObjects(type);
if (objects.Count == 1 && type.IsPerformanceLoaded)
{
// Show/Hide Window!
}
}
}
}
#endregion
#region Public Overriden Methods
/// <summary>
///
/// </summary>
/// <param name="windowKey">Window to run action on</param>
/// <param name="attributes">Window Attributes to use</param>
/// <param name="tag">object to pass into Window</param>
/// <returns>the tag object from the window</returns>
public override object ShowWindow(Enum windowKey, WindowAttributes attributes, object tag)
{
DelegateCollection.Obj_Func func = delegate()
{
object o = CreateInstance(windowKey);
if (AddObject(windowKey, o))
{
Window wpfWin = (Window)o;
wpfWin.Tag = tag;
// Set Attributes
SetAttributesOnWindow(wpfWin, attributes);
// Show
wpfWin.Show();
object retVal = wpfWin.Tag;
wpfWin = null;
return retVal;
}
return null;
};
if (Dispatcher.Thread == System.Threading.Thread.CurrentThread)
{
return func();
}
else
{
object[] parameters = new object[] { windowKey, attributes, tag };
return Dispatcher.Invoke((ShowDelegate)ShowWindow, DispatcherPriority.Normal, parameters);
}
}
/// <summary>
/// Show the WPF Window as a Dialog
/// </summary>
/// <param name="windowKey">Window to run action on</param>
/// <param name="attributes">Window Attributes to use</param>
/// <param name="tag">object to pass into Window</param>
/// <returns>the tag object from the window</returns>
public override object ShowDialog(Enum windowKey, WindowAttributes attributes, object tag)
{
DelegateCollection.Obj_Func func = delegate()
{
object o = CreateInstance(windowKey);
if (AddObject(windowKey, o))
{
Window wpfWin = (Window)o;
wpfWin.Tag = tag;
// Set Attributes
SetAttributesOnWindow(wpfWin, attributes);
// ShowDialog()
wpfWin.ShowDialog();
object retVal = wpfWin.Tag;
DeleteObject(windowKey);
wpfWin = null;
return retVal;
}
return null;
};
if (Dispatcher.Thread == System.Threading.Thread.CurrentThread)
{
return func();
}
else
{
object[] parameters = new object[] { windowKey, attributes, tag };
return Dispatcher.Invoke((ShowDelegate)ShowDialog, DispatcherPriority.Normal, parameters);
}
}
/// <summary>
/// Run any generic action on a window
/// </summary>
/// <param name="windowKey">Window to run action on</param>
/// <param name="action">action to perform on the windo</param>
public override bool RunAction(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action)
{
if (Dispatcher.Thread == System.Threading.Thread.CurrentThread)
{
List<object> objects = GetObjects(windowKey);
object o = null;
if (objects != null)
o = objects.Last();
if (o != null && o is Window && action != null)
return action((Window)o);
else
return action(null);
}
else
{
object[] parameters = new object[] { windowKey, action };
return (bool)Dispatcher.Invoke((ActionDelegate)RunAction, DispatcherPriority.Normal, parameters);
}
}
/// <summary>
/// Hide the Specified Window
/// </summary>
/// <param name="windowKey">Window to run action on</param>
/// <returns>true, if successful, false otherwise</returns>
public override bool HideWindow(Enum windowKey)
{
DelegateCollection.Bool_Param1_Window_Func func = delegate(Window wpfWin)
{
wpfWin.Hide();
return true;
};
return RunAction(windowKey, func);
}
/// <summary>
/// Close the Specified Window
/// </summary>
/// <param name="windowKey">Window to run action on</param>
/// <returns>true, if successful, false otherwise</returns>
public override bool CloseWindow(Enum windowKey)
{
DelegateCollection.Bool_Param1_Window_Func func = delegate(Window wpfWin)
{
DeleteObject(windowKey);
return true;
};
return RunAction(windowKey, func);
}
/// <summary>
/// Dispose of this manager Properly
/// </summary>
public override void Dispose()
{
// We must call the base's ClearAllObjects()
DelegateCollection.Bool_Param1_Window_Func func = delegate(Window wpfWin)
{
ClearAllObjects();
return true;
};
RunAction(null, func);
}
#endregion
#region Private Helpers
/// <summary>
/// Set the Window Attributes as specifed by the WindowAttributes type
/// </summary>
/// <param name="attributes">Attributes to set</param>
/// <param name="wpfWin">Window to set them on</param>
private void SetAttributesOnWindow(Window wpfWin, WindowAttributes attributes)
{
// Set Attributes
if (attributes != null && wpfWin != null)
{
WindowInteropHelper InteropHelper = new WindowInteropHelper(wpfWin);
if (attributes.hWndOwner != IntPtr.Zero)
InteropHelper.Owner = (IntPtr)attributes.hWndOwner;
if (attributes.Height != 0)
wpfWin.Height = attributes.Height;
if (attributes.Width != 0)
wpfWin.Width = attributes.Width;
if (attributes.Left != int.MinValue)
wpfWin.Left = attributes.Left;
if (attributes.Top != int.MinValue)
wpfWin.Top = attributes.Top;
if (!String.IsNullOrEmpty(attributes.Title))
wpfWin.Title = attributes.Title;
}
}
#endregion
}
}

59
Web/HTTP.cs Normal file
View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace Yaulw.Web
{
public class HTTP
{
/// <summary>
/// urlCreated.Text = Url;
/// var toPost = Url.Split('?');
/// var result = HttpPost(toPost[0], toPost[1]);
/// </summary>
/// <param name="uri"></param>
/// <param name="parameters"></param>
/// <returns>String.Empty if error occured, non-empty string otherwise</returns>
string HttpPost(string uri, string parameters)
{
var cookies = new CookieContainer();
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.CookieContainer = cookies;
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(parameters);
Stream os = null;
try
{
webRequest.ContentLength = bytes.Length; //Count bytes to send
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length); //Send it
}
catch (Exception) { /* ignore */ }
finally
{
if (os != null)
{
os.Close();
}
}
try
{
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null)
{ return null; }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
return sr.ReadToEnd().Trim();
}
catch (Exception) { /* ignore */ }
return String.Empty;
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace Yaulw.Web
{
/// <remarks>
///
/// </remarks>
public class WebClientWithTimeout : WebClient
{
/// <summary>
///
/// </summary>
public int Timeout { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="timeout"></param>
public WebClientWithTimeout(int timeout)
{
this.Timeout = timeout;
}
/// <summary>
///
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
protected override WebRequest GetWebRequest(Uri address)
{
var result = base.GetWebRequest(address);
result.Timeout = this.Timeout;
return result;
}
}
}

27
Win32/Advapi32.cs Normal file
View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Yaulw.Win32
{
/// <remarks>
/// Advapi.dll Entry Points * http://pinvoke.net/ *
/// </remarks>
public static class Advapi32
{
/// <summary>
/// Retrieves the current status of the specified service based on the specified information level
/// </summary>
/// <param name="hService">A handle to the service</param>
/// <param name="InfoLevel">The service attributes to be returned</param>
/// <param name="lpBuffer">A pointer to the buffer that receives the status information</param>
/// <param name="cbBufSize">he size of the buffer pointed to by the lpBuffer</param>
/// <param name="pcbBytesNeeded">A pointer to a variable that receives the number of bytes needed to store all status information</param>
/// <returns>If the function succeeds, the return value is nonzero</returns>
[DllImport("Advapi32.dll")]
extern public static bool QueryServiceStatusEx(IntPtr hService, int InfoLevel, ref Structures.SERVICE_STATUS_PROCESS lpBuffer, int cbBufSize, out int pcbBytesNeeded);
}
}

321
Win32/AtomMessenger.cs Normal file
View File

@@ -0,0 +1,321 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Yaulw.Win32
{
/// <remarks>
/// Quick and Easy Atom Window Messages Communication between windows of different
/// Processes.
/// </remarks>
public class AtomMessenger : IDisposable
{
#region Private Members
private const string _AtomMsgIDFormat = "AtomMsgID-[{0}]";
private string _AtomMsgStr = "";
private uint _AtomMsg = 0;
private bool _disposed = false;
// For Posted Atom Messages
private const int MAGIC_NUMBER_POSTED_ATOM_KEYS = 7;
private List<uint> _postedAtomKeys = new List<uint>();
#endregion
#region Construction
/// <summary>
/// Create an Atom Messaging Component with a Unique Identifier.
/// The same Identifier should be used by all applications that want to pass
/// Messages back and forth.
/// ~You need to dispose of this Object only if you plan on using PostAtomMessage()
/// </summary>
/// <param name="UniqueWindowMessageIdentifier">An identifier for the Messaging</param>
public AtomMessenger(Guid UniqueWindowMessageIdentifier)
{
if (UniqueWindowMessageIdentifier == null)
throw new ArgumentNullException();
// Register the Unique Window Message
_AtomMsgStr = String.Format(_AtomMsgIDFormat, UniqueWindowMessageIdentifier);
_AtomMsg = User32.RegisterWindowMessage(_AtomMsgStr);
if (_AtomMsg == 0)
throw new Exception("RegisterWindowMessage Failed");
}
/// <summary>
/// Finalizer
/// </summary>
~AtomMessenger()
{
Dispose(true);
}
#endregion
#region Atom Message Construction Helpers
/// <summary>
/// Retrieve ';' seperated values from an Atom Message
/// </summary>
/// <param name="AtomMessage">an atom message that contains multiple args</param>
/// <returns>multiple args</returns>
public string[] RetrieveMultipleValuesFromAtomMessage(string AtomMessage)
{
if (!String.IsNullOrEmpty(AtomMessage))
return AtomMessage.Split(';');
else
return null;
}
/// <summary>
/// Create ';' seperated Atom message from multiple values
/// </summary>
/// <returns>an Atom Message containing multiple args</returns>
public string SetMultipleValueInAtomMessage(params object[] args)
{
if (args != null)
{
StringBuilder sb = new StringBuilder();
foreach (object a in args)
{
sb.Append(a.ToString());
sb.Append(";");
}
// Remove Trailing ";"
sb = sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
return String.Empty;
}
#endregion
#region Atom Message Identify / Retrieval
/// <summary>
/// Use this to check if the passed in Message is an Atom Message.
/// The identifier of the Message must match the Message registered with the UniqueIdentifier
/// </summary>
/// <param name="m">a Windows.Forms Message</param>
/// <returns>true if the Messages matches the one created by the UniqueIdentifier</returns>
public bool IsAtomMessage(ref Message m)
{
return (m.Msg == _AtomMsg);
}
/// <summary>
/// Retrieves the values passed in by an Atom Message
/// </summary>
/// <param name="m">a Windows.Forms Message</param>
/// <param name="AtomMessage">the Message Retrieved from the Atom</param>
/// <param name="hWndSrc">the source window who send it, if valid</param>
public void GetAtomMessageValues(ref Message m, out string AtomMessage, out IntPtr hWndSrc)
{
AtomMessage = String.Empty;
hWndSrc = IntPtr.Zero;
// Check to make sure this is an Atom Message
if (!IsAtomMessage(ref m))
return;
// Source is passed to us by wParam
if(m.WParam != IntPtr.Zero && User32.IsWindow(m.WParam))
hWndSrc = m.WParam;
// Now retrieve the Atom Message
StringBuilder sb = new StringBuilder( 254 );
uint AtomKey = (uint) m.LParam;
uint slen = Kernel32.GlobalGetAtomName(AtomKey, sb, 254);
if (slen == 0)
return;
// Write out Retrieved Message
AtomMessage = sb.ToString();
}
/// <summary>
/// Retrieves the values passed in by an Atom Message
/// </summary>
/// <param name="m">a Windows.Forms Message</param>
/// <param name="AtomMessage">the Message with multiple values retrieved from the Atom</param>
/// <param name="hWndSrc">the source window who send it, if valid</param>
public void GetAtomMessageValues(ref Message m, out string[] AtomMessage, out IntPtr hWndSrc)
{
AtomMessage = null;
hWndSrc = IntPtr.Zero;
// Check to make sure this is an Atom Message
if (!IsAtomMessage(ref m))
return;
// Source is passed to us by wParam
if (m.WParam != IntPtr.Zero && User32.IsWindow(m.WParam))
hWndSrc = m.WParam;
// Now retrieve the Atom Message
StringBuilder sb = new StringBuilder(254);
uint AtomKey = (uint)m.LParam;
uint slen = Kernel32.GlobalGetAtomName(AtomKey, sb, 254);
if (slen == 0)
return;
// Write out Retrieved Message
AtomMessage = RetrieveMultipleValuesFromAtomMessage(sb.ToString());
}
#endregion
#region Send/Post Atom Message
/// <summary>
/// Sends an Atom Message To the Specified Window or All Windows
/// </summary>
/// <param name="hWndSrc">Sender Windows (Nice to have), in case Receiver Needs it</param>
/// <param name="hWndDst">Can be IntPtr.Zero to BroadCast the Message, otherwise specify window to send to</param>
/// <param name="AtomMessage">The Message to Send * Can not be longer than 254 chars *</param>
public void SendAtomMessage(IntPtr hWndSrc, IntPtr hWndDst, string AtomMessage)
{
// Is Broadcast?
bool bBroadcast = (hWndDst==IntPtr.Zero);
// Check to make sure Atom Message is proper
if(String.IsNullOrEmpty(AtomMessage) || AtomMessage.Length > 254)
throw new ArgumentException("AtomMessage Invalid");
// Register Atom
uint AtomKey = Kernel32.GlobalAddAtom(AtomMessage);
if (AtomKey == 0)
throw new Exception("GlobalAddAtom Failed");
// Send the Message
if(bBroadcast)
User32.SendMessage(Definitions.HWND_BROADCAST, (int)_AtomMsg, hWndSrc, (IntPtr)AtomKey);
else
User32.SendMessage(hWndDst, (int)_AtomMsg, hWndSrc, (IntPtr)AtomKey);
// We are done with the Atom
Kernel32.GlobalDeleteAtom(AtomKey);
}
/// <summary>
/// Sends an Atom Message To the Specified Window or All Windows
/// </summary>
/// <param name="hWndSrc">Sender Windows (Nice to have), in case Receiver Needs it</param>
/// <param name="hWndDst">Can be IntPtr.Zero to BroadCast the Message, otherwise specify window to send to</param>
/// <param name="AtomMessage">The Message to Send that has multiple values * Total string can not be longer than 254 chars *</param>
public void SendAtomMessage(IntPtr hWndSrc, IntPtr hWndDst, string[] AtomMessage)
{
SendAtomMessage(hWndSrc, hWndDst, SetMultipleValueInAtomMessage(AtomMessage));
}
/// <summary>
/// Post an Atom Message To the Specified Window or All Windows
/// </summary>
/// <param name="hWndSrc">Sender Windows (Nice to have), in case Receiver Needs it</param>
/// <param name="hWndDst">Can be IntPtr.Zero to BroadCast the Message, otherwise specify window to send to</param>
/// <param name="AtomMessage">The Message to Send * Can not be longer than 254 chars *</param>
public void PostAtomMessage(IntPtr hWndSrc, IntPtr hWndDst, string AtomMessage)
{
// Is Broadcast?
bool bBroadcast = (hWndDst == IntPtr.Zero);
// Check to make sure Atom Message is proper
if (String.IsNullOrEmpty(AtomMessage) || AtomMessage.Length > 254)
throw new ArgumentException("AtomMessage Invalid");
// Register a new Atom
uint nAtomKey = Kernel32.GlobalAddAtom(AtomMessage);
if (nAtomKey == 0)
throw new Exception("GlobalAddAtom Failed");
// Send the Message
if (bBroadcast)
User32.PostMessage(Definitions.HWND_BROADCAST, (int)_AtomMsg, hWndSrc, (IntPtr)nAtomKey);
else
User32.PostMessage(hWndDst, (int)_AtomMsg, hWndSrc, (IntPtr)nAtomKey);
// Imp! Atom still must get Deleted, that is why we add it to DS
AddPostedAtomKey(nAtomKey);
}
/// <summary>
/// Post an Atom Message To the Specified Window or All Windows
/// </summary>
/// <param name="hWndSrc">Sender Windows (Nice to have), in case Receiver Needs it</param>
/// <param name="hWndDst">Can be IntPtr.Zero to BroadCast the Message, otherwise specify window to send to</param>
/// <param name="AtomMessage">The Message to Send that has multiple values * Can not be longer than 254 chars *</param>
public void PostAtomMessage(IntPtr hWndSrc, IntPtr hWndDst, string[] AtomMessage)
{
PostAtomMessage(hWndSrc, hWndDst, SetMultipleValueInAtomMessage(AtomMessage));
}
#endregion
#region Posted Atom Keys handling
/// <summary>
/// Adds the Specified Posted Atom Key to the Posted Atoms DS.
/// Clears the DS, if MAGIC_NUMBER_POSTED_ATOM_KEY has been reached.
/// </summary>
/// <param name="nKey">a unique AtomKey</param>
private void AddPostedAtomKey(uint nKey)
{
if (_postedAtomKeys.Count >= MAGIC_NUMBER_POSTED_ATOM_KEYS)
DeleteAllPostedAtomKeys();
_postedAtomKeys.Add(nKey);
}
/// <summary>
/// Deletes all posted Atoms and Clears the PostedAtoms DS
/// </summary>
private void DeleteAllPostedAtomKeys()
{
foreach (uint Key in _postedAtomKeys)
Kernel32.GlobalDeleteAtom(Key);
_postedAtomKeys.Clear();
}
#endregion
#region IDisposable Members
/// <summary>
/// Dispose Posted Atom Strings
/// </summary>
public void Dispose()
{
Dispose(true);
// Use SupressFinalize in case a subclass
// of this type implements a finalizer
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose Posted Atom Strings
/// </summary>
/// <param name="disposing">true, if called from within</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (_postedAtomKeys.Count != 0)
DeleteAllPostedAtomKeys();
}
// Indicate that the instance has been disposed.
_postedAtomKeys = null;
_disposed = true;
}
}
#endregion
}
}

116
Win32/COM.cs Normal file
View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace Yaulw.Win32
{
/// <remarks>
/// COM Win32 Helper Functions
/// </remarks>
public static class COM
{
/// <summary>
/// Returns a pointer to an implementation of IBindCtx (a bind context object). This object stores information about a particular moniker-binding operation
/// </summary>
/// <param name="reserved">This parameter is reserved and must be 0</param>
/// <param name="ppbc">Address of an IBindCtx* pointer variable that receives the interface pointer to the new bind context object. </param>
/// <returns>This function can return the standard return values E_OUTOFMEMORY and S_OK</returns>
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
/// <summary>
/// Use this to retrieve the Actice COM Object from the ROT, for the specified progId
/// </summary>
/// <param name="progId"></param>
/// <returns>a valid com object, or null if error occured</returns>
public static Object GetActiceCOMObject(string progId)
{
Object app = null;
try
{
app = Marshal.GetActiveObject(progId);
}
catch (SystemException) { /* ignore */ }
return app;
}
/// <summary>
/// ROT Object Entry
/// </summary>
public struct RunningObject
{
public string name;
public object o;
}
/// <summary>
/// Use this to Get All Running Objects in the ROT
/// </summary>
/// <returns>list of all Runnint Objects in the ROT</returns>
public static List<RunningObject> GetRunningObjects()
{
// Get the table.
var res = new List<RunningObject>();
IBindCtx bc;
CreateBindCtx(0, out bc);
IRunningObjectTable runningObjectTable;
bc.GetRunningObjectTable(out runningObjectTable);
IEnumMoniker monikerEnumerator;
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
// Enumerate and fill our nice dictionary.
IMoniker[] monikers = new IMoniker[1];
IntPtr numFetched = IntPtr.Zero;
while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
{
RunningObject running;
monikers[0].GetDisplayName(bc, null, out running.name);
runningObjectTable.GetObject(monikers[0], out running.o);
res.Add(running);
}
return res;
}
/// <summary>
/// Use this to Get A specific type of Object from the ROT
/// </summary>
/// <returns>List of a specific type of Object in the ROT</returns>
public static List<T> GetRunningObjectsOfType<T>()
{
// Get the table.
var res = new List<T>();
IBindCtx bc;
CreateBindCtx(0, out bc);
IRunningObjectTable runningObjectTable;
bc.GetRunningObjectTable(out runningObjectTable);
IEnumMoniker monikerEnumerator;
runningObjectTable.EnumRunning(out monikerEnumerator);
monikerEnumerator.Reset();
// Enumerate and fill our nice dictionary.
IMoniker[] monikers = new IMoniker[1];
IntPtr numFetched = IntPtr.Zero;
while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
{
object o;
runningObjectTable.GetObject(monikers[0], out o);
if (o is T)
res.Add((T)o);
o = null;
}
return res;
}
}
}

70
Win32/Convert.cs Normal file
View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Yaulw.Win32
{
/// <remarks>
/// Helper class to Convert Win32 Structures to DotNet and vice versa
/// </remarks>
public static class Convert
{
/// <summary>
/// Use this to Convert to Win32 Window Message Enum from a C# Message
/// </summary>
/// <param name="m">a C# Message</param>
/// <returns>a Win32 Message Enum</returns>
public static Definitions.WM MessageToWin32WM(Message m)
{
Definitions.WM wm = Definitions.WM.WM_NULL;
try { wm = (Definitions.WM)m.Msg; }
catch (Exception) { wm = Definitions.WM.WM_NULL; }
return wm;
}
/// <summary>
/// Use this to Convert to a C# Rectangle from a Win32 RECT
/// </summary>
/// <param name="rect">a Win32 Rect</param>
/// <returns>a C# Rectancle</returns>
public static Rectangle RECTToRectangle(Structures.RECT rect)
{
return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
}
/// <summary>
/// Use this to Convert a Win32 RECT to a C# Rectangle
/// </summary>
/// <param name="rect">a C# Rectangle</param>
/// <returns>a Win32 Rect</returns>
public static Structures.RECT RectangleToRECT(Rectangle rect)
{
return Structures.RECT.FromXYWH(rect.Left, rect.Top, rect.Width, rect.Height);
}
#region Win32Owner
/// <remarks>
/// a IWin32Window Object commonly used by WinForms
/// </remarks>
public class Win32Owner : IWin32Window
{
public IntPtr Handle { get; set; }
}
/// <summary>
/// Convert a Handle to a Win32Owner Object
/// </summary>
/// <param name="hWnd">pass in a Window Handle</param>
/// <returns>a newly created Win32Owner Object</returns>
public static IWin32Window ConverthWndToIWin32Window(IntPtr hWnd)
{
return new Win32Owner() { Handle = hWnd };
}
#endregion
}
}

601
Win32/Definitions.cs Normal file
View File

@@ -0,0 +1,601 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Yaulw.Win32
{
/// <remarks>
/// Win32 Enums and Consts (Definitions)
/// </remarks>
public static class Definitions
{
#region Constants
/// <summary>
/// Virtual Key Board Key Up Event
/// </summary>
public const ushort KEYEVENTF_KEYUP = 0x0002;
/// <summary>
/// Source Copy Option
/// </summary>
public const int SRCCOPY = 13369376;
/// <summary>
/// Default Monitor Nearest
/// </summary>
public const int MONITOR_DEFAULTTONEAREST = 0x00000002;
/// <summary>
/// Universal Max Path Const used in Many Win32 Paths
/// </summary>
public const int MAX_PATH = 255;
/// <summary>
/// For Windows Hooking
/// </summary>
public const int WH_CBT = 5;
/// <summary>
/// System is about to activate a window
/// </summary>
public const int HCBT_ACTIVATE = 5;
/// <summary>
/// Used for SendMessage/PostMessage
/// </summary>
public static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
#region Service Constants - Advapi32.dll
/// <summary>
/// Service Option
/// </summary>
public const int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
/// <summary>
/// Service Option
/// </summary>
public const int SERVICE_RUNS_IN_SYSTEM_PROCESS = 0x00000001;
/// <summary>
/// Service Option
/// </summary>
public const int SC_STATUS_PROCESS_INFO = 0;
#endregion
#endregion
#region Enums
/// <summary>
/// AssocQueryString Options
/// </summary>
public enum AssocF : ushort
{
Init_NoRemapCLSID = 0x1,
Init_ByExeName = 0x2,
Open_ByExeName = 0x2,
Init_DefaultToStar = 0x4,
Init_DefaultToFolder = 0x8,
NoUserSettings = 0x10,
NoTruncate = 0x20,
Verify = 0x40,
RemapRunDll = 0x80,
NoFixUps = 0x100,
IgnoreBaseClass = 0x200
}
/// <summary>
/// DDE Commands
/// </summary>
public enum AssocStr : ushort
{
Command = 1,
Executable,
FriendlyDocName,
FriendlyAppName,
NoOpen,
ShellNewValue,
DDECommand,
DDEIfExec,
DDEApplication,
DDETopic
}
/// <summary>
/// For Process DEP
/// </summary>
public enum DEP : int
{
PROCESS_DEP_DISABLE = 0x00000000,
PROCESS_DEP_ENABLE = 0x00000001,
PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION = 0x00000002,
}
/// <summary>
/// Layered Windows
/// </summary>
public enum LayeredWindowAttribute_Value : int
{
LWA_COLORKEY = 0x00000001,
LWA_ALPHA = 0x00000002
}
/// <summary>
/// Mouse Events
/// </summary>
public enum MouseEvent : ushort
{
MOUSEEVENTF_LEFTDOWN = 0x02,
MOUSEEVENTF_LEFTUP = 0x04,
MOUSEEVENTF_RIGHTDOWN = 0x08,
MOUSEEVENTF_RIGHTUP = 0x10
}
/// <summary>
/// OpenProcess Values
/// </summary>
public enum OpenProcess_Value : int
{
DELETE = 0x00010000,
READ_CONTROL = 0x00020000,
SYNCHRONIZE = 0x00100000,
WRITE_DAC = 0x00040000,
WRITE_OWNER = 0x00080000
}
/// <summary>
/// Scrollbar values
/// </summary>
public enum ScrollBar_Value : int
{
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2,
SB_BOTH = 3,
}
/// <summary>
/// Set Window Pos Actions
/// </summary>
public enum SetWindowPos_Action : uint
{
SWP_NOSIZE = 0x0001,
SWP_NOMOVE = 0x0002,
SWP_NOZORDER = 0x0004,
SWP_NOREDRAW = 0x0008,
SWP_NOACTIVATE = 0x0010,
SWP_FRAMECHANGED = 0x0020,
SWP_SHOWWINDOW = 0x0040,
SWP_HIDEWINDOW = 0x0080,
SWP_NOCOPYBITS = 0x0100,
SWP_NOOWNERZORDER = 0x0200,
SWP_NOSENDCHANGING = 0x0400,
SWP_DRAWFRAME = SWP_FRAMECHANGED,
SWP_NOREPOSITION = SWP_NOOWNERZORDER
}
/// <summary>
/// Show Window Actions
/// </summary>
public enum ShowWindow_Action : int
{
SW_HIDE = 0,
SW_SHOWNORMAL = 1,
SW_NORMAL = 1,
SW_SHOWMINIMIZED = 2,
SW_SHOWMAXIMIZED = 3,
SW_MAXIMIZE = 3,
SW_SHOWNOACTIVATE = 4,
SW_SHOW = 5,
SW_MINIMIZE = 6,
SW_SHOWMINNOACTIVE = 7,
SW_SHOWNA = 8,
SW_RESTORE = 9,
SW_SHOWDEFAULT = 10,
SW_FORCEMINIMIZE = 11,
SW_MAX = 11
}
/// <summary>
/// System Metrix
/// </summary>
public enum SystemMetric_Value : int
{
SM_CXSCREEN = 0,
SM_CYSCREEN = 1,
SM_CXVSCROLL = 2,
SM_CYHSCROLL = 3,
SM_CYCAPTION = 4,
SM_CXBORDER = 5,
SM_CYBORDER = 6,
SM_CXDLGFRAME = 7,
SM_CYDLGFRAME = 8,
SM_CYVTHUMB = 9,
SM_CXHTHUMB = 10,
SM_CXICON = 11,
SM_CYICON = 12,
SM_CXCURSOR = 13,
SM_CYCURSOR = 14,
SM_CYMENU = 15,
SM_CXFULLSCREEN = 16,
SM_CYFULLSCREEN = 17,
SM_CYKANJIWINDOW = 18,
SM_MOUSEPRESENT = 19,
SM_CYVSCROLL = 20,
SM_CXHSCROLL = 21,
SM_DEBUG = 22,
SM_SWAPBUTTON = 23,
SM_RESERVED1 = 24,
SM_RESERVED2 = 25,
SM_RESERVED3 = 26,
SM_RESERVED4 = 27,
SM_CXMIN = 28,
SM_CYMIN = 29,
SM_CXSIZE = 30,
SM_CYSIZE = 31,
SM_CXFRAME = 32,
SM_CYFRAME = 33,
SM_CXMINTRACK = 34,
SM_CYMINTRACK = 35,
SM_CXDOUBLECLK = 36,
SM_CYDOUBLECLK = 37,
SM_CXICONSPACING = 38,
SM_CYICONSPACING = 39,
SM_MENUDROPALIGNMENT = 40,
SM_PENWINDOWS = 41,
SM_DBCSENABLED = 42,
SM_CMOUSEBUTTONS = 43
}
/// <summary>
/// GetWindowLong Values
/// </summary>
public enum WindowLong_Value : int
{
GWL_EXSTYLE = -20,
GWL_STYLE = -16,
GWL_WNDPROC = -4,
GWL_HINSTANCE = -6,
GWL_ID = -12,
GWL_USERDATA = -21,
DWL_DLGPROC = 4,
DWL_MSGRESULT = 0,
DWL_USER = 8
}
/// <summary>
/// Window Positions
/// </summary>
public enum WindowPos_Value : int
{
HWND_TOP = 0,
HWND_BOTTOM = 1,
HWND_TOPMOST = -1,
HWND_NOTOPMOST = -2
}
/// <summary>
/// Windows Styles
/// </summary>
public enum WindowStyle_Value : uint
{
WS_MAXIMIZE = 0x01000000,
WS_VISIBLE = 0x10000000,
WS_POPUP = 0x80000000,
WS_BORDER = 0x00800000,
WS_CAPTION = 0x00C00000,
WS_CHILD = 0x40000000,
WS_CHILDWINDOW = 0x40000000,
WS_EX_CLIENTEDGE = 0x00000200,
WS_CLIPCHILDREN = 0x02000000,
WS_CLIPSIBLINGS = 0x04000000,
WS_DISABLED = 0x08000000,
WS_DLGFRAME = 0x00400000,
WS_GROUP = 0x00020000,
}
/// <summary>
/// Windows Messages
/// </summary>
public enum WM : int
{
WM_NULL = 0x0000,
WM_CREATE = 0x0001,
WM_DESTROY = 0x0002,
WM_MOVE = 0x0003,
WM_SIZE = 0x0005,
WM_ACTIVATE = 0x0006,
WM_SETFOCUS = 0x0007,
WM_KILLFOCUS = 0x0008,
WM_ENABLE = 0x000A,
WM_SETREDRAW = 0x000B,
WM_SETTEXT = 0x000C,
WM_GETTEXT = 0x000D,
WM_GETTEXTLENGTH = 0x000E,
WM_PAINT = 0x000F,
WM_CLOSE = 0x0010,
WM_QUERYENDSESSION = 0x0011,
WM_QUIT = 0x0012,
WM_QUERYOPEN = 0x0013,
WM_ERASEBKGND = 0x0014,
WM_SYSCOLORCHANGE = 0x0015,
WM_ENDSESSION = 0x0016,
WM_SHOWWINDOW = 0x0018,
WM_CTLCOLOR = 0x0019,
WM_WININICHANGE = 0x001A,
WM_SETTINGCHANGE = 0x001A,
WM_DEVMODECHANGE = 0x001B,
WM_ACTIVATEAPP = 0x001C,
WM_FONTCHANGE = 0x001D,
WM_TIMECHANGE = 0x001E,
WM_CANCELMODE = 0x001F,
WM_SETCURSOR = 0x0020,
WM_MOUSEACTIVATE = 0x0021,
WM_CHILDACTIVATE = 0x0022,
WM_QUEUESYNC = 0x0023,
WM_GETMINMAXINFO = 0x0024,
WM_PAINTICON = 0x0026,
WM_ICONERASEBKGND = 0x0027,
WM_NEXTDLGCTL = 0x0028,
WM_SPOOLERSTATUS = 0x002A,
WM_DRAWITEM = 0x002B,
WM_MEASUREITEM = 0x002C,
WM_DELETEITEM = 0x002D,
WM_VKEYTOITEM = 0x002E,
WM_CHARTOITEM = 0x002F,
WM_SETFONT = 0x0030,
WM_GETFONT = 0x0031,
WM_SETHOTKEY = 0x0032,
WM_GETHOTKEY = 0x0033,
WM_QUERYDRAGICON = 0x0037,
WM_COMPAREITEM = 0x0039,
WM_GETOBJECT = 0x003D,
WM_COMPACTING = 0x0041,
WM_COMMNOTIFY = 0x0044,
WM_WINDOWPOSCHANGING = 0x0046,
WM_WINDOWPOSCHANGED = 0x0047,
WM_POWER = 0x0048,
WM_COPYDATA = 0x004A,
WM_CANCELJOURNAL = 0x004B,
WM_NOTIFY = 0x004E,
WM_INPUTLANGCHANGEREQUEST = 0x0050,
WM_INPUTLANGCHANGE = 0x0051,
WM_TCARD = 0x0052,
WM_HELP = 0x0053,
WM_USERCHANGED = 0x0054,
WM_NOTIFYFORMAT = 0x0055,
WM_CONTEXTMENU = 0x007B,
WM_STYLECHANGING = 0x007C,
WM_STYLECHANGED = 0x007D,
WM_DISPLAYCHANGE = 0x007E,
WM_GETICON = 0x007F,
WM_SETICON = 0x0080,
WM_NCCREATE = 0x0081,
WM_NCDESTROY = 0x0082,
WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x0084,
WM_NCPAINT = 0x0085,
WM_NCACTIVATE = 0x0086,
WM_GETDLGCODE = 0x0087,
WM_SYNCPAINT = 0x0088,
WM_NCMOUSEMOVE = 0x00A0,
WM_NCLBUTTONDOWN = 0x00A1,
WM_NCLBUTTONUP = 0x00A2,
WM_NCLBUTTONDBLCLK = 0x00A3,
WM_NCRBUTTONDOWN = 0x00A4,
WM_NCRBUTTONUP = 0x00A5,
WM_NCRBUTTONDBLCLK = 0x00A6,
WM_NCMBUTTONDOWN = 0x00A7,
WM_NCMBUTTONUP = 0x00A8,
WM_NCMBUTTONDBLCLK = 0x00A9,
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
WM_CHAR = 0x0102,
WM_DEADCHAR = 0x0103,
WM_SYSKEYDOWN = 0x0104,
WM_SYSKEYUP = 0x0105,
WM_SYSCHAR = 0x0106,
WM_SYSDEADCHAR = 0x0107,
WM_KEYLAST = 0x0108,
WM_IME_STARTCOMPOSITION = 0x010D,
WM_IME_ENDCOMPOSITION = 0x010E,
WM_IME_COMPOSITION = 0x010F,
WM_IME_KEYLAST = 0x010F,
WM_INITDIALOG = 0x0110,
WM_COMMAND = 0x0111,
WM_SYSCOMMAND = 0x0112,
WM_TIMER = 0x0113,
WM_HSCROLL = 0x0114,
WM_VSCROLL = 0x0115,
WM_INITMENU = 0x0116,
WM_INITMENUPOPUP = 0x0117,
WM_MENUSELECT = 0x011F,
WM_MENUCHAR = 0x0120,
WM_ENTERIDLE = 0x0121,
WM_MENURBUTTONUP = 0x0122,
WM_MENUDRAG = 0x0123,
WM_MENUGETOBJECT = 0x0124,
WM_UNINITMENUPOPUP = 0x0125,
WM_MENUCOMMAND = 0x0126,
WM_CTLCOLORMSGBOX = 0x0132,
WM_CTLCOLOREDIT = 0x0133,
WM_CTLCOLORLISTBOX = 0x0134,
WM_CTLCOLORBTN = 0x0135,
WM_CTLCOLORDLG = 0x0136,
WM_CTLCOLORSCROLLBAR = 0x0137,
WM_CTLCOLORSTATIC = 0x0138,
WM_MOUSEMOVE = 0x0200,
WM_LBUTTONDOWN = 0x0201,
WM_LBUTTONUP = 0x0202,
WM_LBUTTONDBLCLK = 0x0203,
WM_RBUTTONDOWN = 0x0204,
WM_RBUTTONUP = 0x0205,
WM_RBUTTONDBLCLK = 0x0206,
WM_MBUTTONDOWN = 0x0207,
WM_MBUTTONUP = 0x0208,
WM_MBUTTONDBLCLK = 0x0209,
WM_MOUSEWHEEL = 0x020A,
WM_XBUTTONDOWN = 0x020B,
WM_XBUTTONUP = 0x020C,
WM_XBUTTONDBLCLK = 0x020D,
WM_PARENTNOTIFY = 0x0210,
WM_ENTERMENULOOP = 0x0211,
WM_EXITMENULOOP = 0x0212,
WM_NEXTMENU = 0x0213,
WM_SIZING = 0x0214,
WM_CAPTURECHANGED = 0x0215,
WM_MOVING = 0x0216,
WM_DEVICECHANGE = 0x0219,
WM_MDICREATE = 0x0220,
WM_MDIDESTROY = 0x0221,
WM_MDIACTIVATE = 0x0222,
WM_MDIRESTORE = 0x0223,
WM_MDINEXT = 0x0224,
WM_MDIMAXIMIZE = 0x0225,
WM_MDITILE = 0x0226,
WM_MDICASCADE = 0x0227,
WM_MDIICONARRANGE = 0x0228,
WM_MDIGETACTIVE = 0x0229,
WM_MDISETMENU = 0x0230,
WM_ENTERSIZEMOVE = 0x0231,
WM_EXITSIZEMOVE = 0x0232,
WM_DROPFILES = 0x0233,
WM_MDIREFRESHMENU = 0x0234,
WM_IME_SETCONTEXT = 0x0281,
WM_IME_NOTIFY = 0x0282,
WM_IME_CONTROL = 0x0283,
WM_IME_COMPOSITIONFULL = 0x0284,
WM_IME_SELECT = 0x0285,
WM_IME_CHAR = 0x0286,
WM_IME_REQUEST = 0x0288,
WM_IME_KEYDOWN = 0x0290,
WM_IME_KEYUP = 0x0291,
WM_MOUSEHOVER = 0x02A1,
WM_MOUSELEAVE = 0x02A3,
WM_CUT = 0x0300,
WM_COPY = 0x0301,
WM_PASTE = 0x0302,
WM_CLEAR = 0x0303,
WM_UNDO = 0x0304,
WM_RENDERFORMAT = 0x0305,
WM_RENDERALLFORMATS = 0x0306,
WM_DESTROYCLIPBOARD = 0x0307,
WM_DRAWCLIPBOARD = 0x0308,
WM_PAINTCLIPBOARD = 0x0309,
WM_VSCROLLCLIPBOARD = 0x030A,
WM_SIZECLIPBOARD = 0x030B,
WM_ASKCBFORMATNAME = 0x030C,
WM_CHANGECBCHAIN = 0x030D,
WM_HSCROLLCLIPBOARD = 0x030E,
WM_QUERYNEWPALETTE = 0x030F,
WM_PALETTEISCHANGING = 0x0310,
WM_PALETTECHANGED = 0x0311,
WM_HOTKEY = 0x0312,
WM_PRINT = 0x0317,
WM_PRINTCLIENT = 0x0318,
WM_HANDHELDFIRST = 0x0358,
WM_HANDHELDLAST = 0x035F,
WM_AFXFIRST = 0x0360,
WM_AFXLAST = 0x037F,
WM_PENWINFIRST = 0x0380,
WM_PENWINLAST = 0x038F,
WM_APP = 0x8000,
WM_USER = 0x0400,
WM_REFLECT = WM_USER + 0x1c00,
WM_CHANGEUISTATE = 0x0127,
WM_UPDATEUISTATE = 0x0128,
WM_QUERYUISTATE = 0x0129
}
/// <summary>
/// Virtual Keyboard Keys
/// </summary>
public enum VK : ushort
{
SHIFT = 0x10,
CONTROL = 0x11,
MENU = 0x12,
ESCAPE = 0x1B,
BACK = 0x08,
TAB = 0x09,
RETURN = 0x0D,
SPACE = 0x20,
PRIOR = 0x21,
NEXT = 0x22,
END = 0x23,
HOME = 0x24,
LEFT = 0x25,
UP = 0x26,
RIGHT = 0x27,
DOWN = 0x28,
SELECT = 0x29,
PRINT = 0x2A,
EXECUTE = 0x2B,
SNAPSHOT = 0x2C,
INSERT = 0x2D,
DELETE = 0x2E,
HELP = 0x2F,
NUMPAD0 = 0x60,
NUMPAD1 = 0x61,
NUMPAD2 = 0x62,
NUMPAD3 = 0x63,
NUMPAD4 = 0x64,
NUMPAD5 = 0x65,
NUMPAD6 = 0x66,
NUMPAD7 = 0x67,
NUMPAD8 = 0x68,
NUMPAD9 = 0x69,
MULTIPLY = 0x6A,
ADD = 0x6B,
SEPARATOR = 0x6C,
SUBTRACT = 0x6D,
DECIMAL = 0x6E,
DIVIDE = 0x6F,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7A,
F12 = 0x7B,
OEM_1 = 0xBA, // ',:' for US
OEM_PLUS = 0xBB, // '+' any country
OEM_COMMA = 0xBC, // ',' any country
OEM_MINUS = 0xBD, // '-' any country
OEM_PERIOD = 0xBE, // '.' any country
OEM_2 = 0xBF, // '/?' for US
OEM_3 = 0xC0, // '`~' for US
MEDIA_NEXT_TRACK = 0xB0,
MEDIA_PREV_TRACK = 0xB1,
MEDIA_STOP = 0xB2,
MEDIA_PLAY_PAUSE = 0xB3,
LWIN = 0x5B,
RWIN = 0x5C
}
/// <summary>
/// enum to hold the possible connection states
/// </summary>
[Flags]
public enum ConnectionStatusEnum : int
{
INTERNET_CONNECTION_MODEM = 0x1,
INTERNET_CONNECTION_LAN = 0x2,
INTERNET_CONNECTION_PROXY = 0x4,
INTERNET_RAS_INSTALLED = 0x10,
INTERNET_CONNECTION_OFFLINE = 0x20,
INTERNET_CONNECTION_CONFIGURED = 0x40
}
#endregion
}
}

388
Win32/Functions.cs Normal file
View File

@@ -0,0 +1,388 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using SysIO = System.IO;
using Diag = System.Diagnostics;
using Yaulw.Tools;
namespace Yaulw.Win32
{
/// <remarks>
/// Common Win32 .Net Wrapper Functions around Win32 for easier consumption by C#
/// </remarks>
public static class Functions
{
#region Byte / Word
/// <summary>
/// Returns the Low word of the specified int
/// </summary>
/// <param name="n">int to retrieve low word from</param>
/// <returns>low word of the int</returns>
public static int LOWORD(int n) { return (n & 0xffff); }
/// <summary>
/// Returns the Low byte of the specified int
/// </summary>
/// <param name="n">int to retrieve low byte from</param>
/// <returns>low byte of the int</returns>
public static int LOBYTE(int n) { return (n & 0xff); }
/// <summary>
/// Returns the High word of the specified int
/// </summary>
/// <param name="n">int to retrieve high word from</param>
/// <returns>high word of the int</returns>
public static int HIWORD(int n) { return ((n >> 16) & 0xffff); }
/// <summary>
/// Returns the High byte of the specified int
/// </summary>
/// <param name="n">int to retrieve high byte from</param>
/// <returns>high byte of the int</returns>
public static int HIBYTE(int n) { return ((n >> 8) & 0xff); }
#endregion
#region RGB
/// <summary>
/// Win32 RGB
/// </summary>
/// <param name="r">red value as int</param>
/// <param name="g">green value as int</param>
/// <param name="b">blue value as int</param>
/// <returns>returns a Win32 RGB Value as int</returns>
public static int RGB(int r, int g, int b)
{
int rs = r & 0xffff;
int gs = (g << 8) & 0xffff;
int bs = (b << 16) & 0xffff;
return (rs | gs | bs);
}
/// <summary>
/// Retrieve the Red Value from Win32 RGB Value
/// </summary>
/// <param name="rgbDWORD"></param>
/// <returns>returns Red value</returns>
public static int GetRValue(int rgbDWORD)
{
return LOBYTE(rgbDWORD);
}
/// <summary>
/// Retrieve the Green Value from Win32 RGB Value
/// </summary>
/// <param name="rgbDWORD"></param>
/// <returns>returns Green value</returns>
public static int GetGValue(int rgbDWORD)
{
return (LOBYTE(rgbDWORD >> 8));
}
/// <summary>
/// Retrieve the Blue Value from Win32 RGB Value
/// </summary>
/// <param name="rgbDWORD"></param>
/// <returns>returns Blue value</returns>
public static int GetBValue(int rgbDWORD)
{
return (LOBYTE(rgbDWORD >> 16));
}
#endregion
#region Keyboard Functionallity
/// <summary>
/// Use this Function to determine whether the user is holding down a specified key
/// </summary>
/// <param name="vKey">VK such as Ctrl/Alt/Shift</param>
/// <returns>true if pressed down, false otherwise</returns>
public static bool IsKeyPressed(Definitions.VK vKey)
{
short retVal = User32.GetKeyState(vKey);
return (retVal < 0);
}
#endregion
#region ClientRect Functionallity
/// <summary>
/// Get a windows client rectangle
/// </summary>
/// <param name="hWnd">A Window Handle</param>
/// <returns>A Rectangle</returns>
public static Rectangle GetClientRect(IntPtr hWnd)
{
Structures.RECT rect = new Structures.RECT();
User32.GetClientRect(hWnd, out rect);
return Convert.RECTToRectangle(rect);
}
/// <summary>
/// Get a windows rectangle
/// </summary>
/// <param name="hWnd">The Window handle</param>
/// <returns>A Rectangle</returns>
public static Rectangle GetWindowRect(IntPtr hWnd)
{
Structures.RECT rect = new Structures.RECT();
User32.GetWindowRect(hWnd, out rect);
return Convert.RECTToRectangle(rect);
}
/// <summary>
/// Returns the Client Size, taking into account the Chrome width
/// </summary>
/// <param name="hWnd">A Window Handle</param>
/// <returns>A Rectangle</returns>
public static Rectangle GetAbsoluteClientRect(IntPtr hWnd)
{
Rectangle windowRect = GetWindowRect(hWnd);
Rectangle clientRect = GetClientRect(hWnd);
int chromeWidth = (int)((windowRect.Width - clientRect.Width) / 2);
return new Rectangle(new Point(windowRect.X + chromeWidth, windowRect.Y + (windowRect.Height - clientRect.Height - chromeWidth)), clientRect.Size);
}
#endregion
#region Window Functionallity
/// <summary>
/// Use this to get the name of a Window Class
/// </summary>
/// <param name="hWnd">A Window Handle</param>
/// <returns>The name of the Window Class</returns>
public static string GetWindowClassName(IntPtr hWnd)
{
StringBuilder ClassName = new StringBuilder(100);
int nRet = User32.GetClassName(hWnd, ClassName, ClassName.Capacity);
return ClassName.ToString();
}
/// <summary>
/// Use this to get the text of a Window
/// </summary>
/// <param name="hWnd">A Window Handle</param>
/// <returns>The window Text</returns>
public static string GetWindowText(IntPtr hWnd)
{
int length = User32.GetWindowTextLength(hWnd);
StringBuilder sb = new StringBuilder(length + 1);
User32.GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
/// <summary>
/// Get the Window Text of a Dialog Item
/// </summary>
/// <param name="hDlg">handle to Dialog</param>
/// <param name="nIDDlgItem">uint Dialog Item</param>
/// <returns>Window Text from the Dialog Item</returns>
public static string GetDlgItemText(IntPtr hDlg, int nIDDlgItem)
{
// Get the handle of the dialog item
IntPtr hItem = User32.GetDlgItem(hDlg, nIDDlgItem);
if (hItem == IntPtr.Zero)
return String.Empty;
return GetWindowText(hItem);
}
/// <summary>
/// Use this to retrieve the Process Object for a specific Window Handle
/// </summary>
/// <param name="hWnd">A Window Handle</param>
/// <returns>A valid Process object or Null if error occured</returns>
public static System.Diagnostics.Process GetProcessFromWindowHandle(IntPtr hWnd)
{
int findPID = 0;
User32.GetWindowThreadProcessId(hWnd, ref findPID);
System.Diagnostics.Process process = null;
try
{
if (findPID > 0)
process = System.Diagnostics.Process.GetProcessById(findPID);
}
catch (ArgumentException) { /* ignore */ }
return process;
}
/// <summary>
/// Find the first top level window for the specified process
/// </summary>
/// <param name="pid">Process ID</param>
/// <returns>the hWnd for the first Window of the specifed or IntPtr.Zero if none found</returns>
public static IntPtr GetFirstTopLevelWindowForProcess(int pid)
{
IntPtr Result = IntPtr.Zero;
// Enumerate the top-level windows
User32.EnumWindowsProc proc = delegate(IntPtr hWnd, IntPtr lParam)
{
// Find the first Window that belongs to the specified Process
if (User32.IsWindowVisible(hWnd) && (pid == GetProcessFromWindowHandle(hWnd).Id))
{
Result = hWnd;
return false;
}
return true; // Keep Looking
};
User32.EnumWindows(proc, IntPtr.Zero);
// yippie
return Result;
}
/// <summary>
///
/// </summary>
/// <param name="pid"></param>
/// <returns></returns>
public static IntPtr GetTopLevelChildWindowForProcess(int pid)
{
// To Do
return IntPtr.Zero;
}
#endregion
#region Desktop Window Functionallity
/// <summary>
/// Get's the Desktop Window as a Win32Window Object
/// </summary>
/// <returns>a Win32Window Object</returns>
public static IWin32Window GetDestopWindow()
{
return Convert.ConverthWndToIWin32Window(User32.GetDesktopWindow());
}
/// <summary>
/// Refreshes orphaned Icons in the Taskbar
/// <seealso cref="http://stackoverflow.com/questions/74723/can-you-send-a-signal-to-windows-explorer-to-make-it-refresh-the-systray-icons"/>
/// <seealso cref="http://malwareanalysis.com/CommunityServer/blogs/geffner/archive/2008/02/15/985.aspx"/>
/// </summary>
public static void RefreshTaskbarNotificationArea()
{
// Find the Notification Area
IntPtr hNotificationArea = IntPtr.Zero;
hNotificationArea = User32.FindWindowEx
(User32.FW(User32.FW(User32.FW(IntPtr.Zero, "Shell_TrayWnd"), "TrayNotifyWnd"), "SysPager"),
IntPtr.Zero,
"ToolbarWindow32",
"Notification Area");
if (hNotificationArea == IntPtr.Zero || !User32.IsWindow(hNotificationArea))
return;
// Get the Client Rect of the Notification Area
Structures.RECT r;
User32.GetClientRect(hNotificationArea, out r);
// Send Mouse Messages to the Notification Area
for (int x = 0; x < r.right; x += 5)
for (int y = 0; y < r.bottom; y += 5)
User32.SendMessage(hNotificationArea, (int) Definitions.WM.WM_MOUSEMOVE, (IntPtr) 0, (IntPtr) ((y << 16) + x));
}
#endregion
#region Process Kernel Functionallity
// SetProcessDEPPolicy Helpers
private delegate bool SetProcessDEPPolicy_Delegate(int dwFlags);
private static SetProcessDEPPolicy_Delegate SetProcessPolicy = null;
/// <summary>
/// Use SetProcessDEPPolicy to set the DEP Policy for the currently running
/// Process. This function checks to make sure that kernel32 has the function,
/// before calling it. For Windows Systems that don't have DEP.
/// </summary>
/// <param name="dep">the specified dep to set</param>
/// <returns>the return value of the SetProcessDEPPolicy, or false if it doesn't exist</returns>
public static bool SetProcessDEPPolicy(Definitions.DEP dep)
{
IntPtr hKernel32 = Kernel32.LoadLibrary("Kernel32.dll"); // Get the DLL
if (hKernel32 != IntPtr.Zero)
{
IntPtr procaddr = IntPtr.Zero;
procaddr = Kernel32.GetProcAddress(hKernel32, "SetProcessDEPPolicy"); // Get the Function
if (procaddr != null)
{
// Cast the Delegate
SetProcessPolicy = (SetProcessDEPPolicy_Delegate)Marshal.GetDelegateForFunctionPointer(procaddr, typeof(SetProcessDEPPolicy_Delegate));
// Call it * Disabling DEP *
return SetProcessPolicy((int)dep);
}
}
return false;
}
#endregion
#region Short / Long FileName N' Path Conversions
/// <summary>
/// Converts a LongFileNameNPath (Modern Windows Path) into a ShortFileNPath (Old Dos 8.3)
/// ~File Must exist on the system
/// </summary>
/// <param name="longFileNameNPath">Long (Modern Windows Path) FileNameNPath or Path</param>
/// <returns>Old Dos 8.3 Path</returns>
public static string GetShortFileNameNPathOrPath(string longFileNameNPathOrPath)
{
if (String.IsNullOrEmpty(longFileNameNPathOrPath))
return String.Empty;
// File MUST exist on the system * Otherwise conversions will fail *
if(PathNaming.PathContainsFile(longFileNameNPathOrPath) && !SysIO.File.Exists(longFileNameNPathOrPath))
return String.Empty;
// Directory MUST exist on the system * Otherwise conversions will fail *
if(!PathNaming.PathContainsFile(longFileNameNPathOrPath) && !SysIO.Directory.Exists(longFileNameNPathOrPath))
return String.Empty;
if (String.IsNullOrEmpty(longFileNameNPathOrPath) || !SysIO.Directory.Exists(longFileNameNPathOrPath))
return "";
StringBuilder sb = new StringBuilder(Definitions.MAX_PATH);
Kernel32.GetShortPathName(longFileNameNPathOrPath, sb, sb.Capacity);
return sb.ToString();
}
/// <summary>
/// Converts a ShortFileNameNPath (Old Dos 8.3) into a long (Modern Windows Path)
/// ~File Must exist on the system
/// </summary>
/// <param name="shortFileNameNPathOrPath">Old Dos 8.3 FileNameNPath or Path</param>
/// <returns>new Modern Windows Path</returns>
public static string GetLongFileNameNPathOrPath(string shortFileNameNPathOrPath)
{
if (String.IsNullOrEmpty(shortFileNameNPathOrPath))
return String.Empty;
// File MUST exist on the system * Otherwise conversions will fail *
if (PathNaming.PathContainsFile(shortFileNameNPathOrPath) && !SysIO.File.Exists(shortFileNameNPathOrPath))
return String.Empty;
// Directory MUST exist on the system * Otherwise conversions will fail *
if (!PathNaming.PathContainsFile(shortFileNameNPathOrPath) && !SysIO.Directory.Exists(shortFileNameNPathOrPath))
return String.Empty;
StringBuilder sb = new StringBuilder(Definitions.MAX_PATH);
Kernel32.GetLongPathName(shortFileNameNPathOrPath, sb, sb.Capacity);
return sb.ToString();
}
#endregion
}
}

85
Win32/Gdi32.cs Normal file
View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Yaulw.Win32
{
/// <remarks>
/// Gdi32.dll Entry Points * http://pinvoke.net/ *
/// </remarks>
public static class Gdi32
{
/// <summary>
/// The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from
/// the specified source device context into a destination device context.
/// </summary>
/// <param name="hdcDest">A handle to the destination device context</param>
/// <param name="xDest">The x-coordinate, in logical units, of the upper-left corner of the destination rectangle</param>
/// <param name="yDest">The y-coordinate, in logical units, of the upper-left corner of the destination rectangle</param>
/// <param name="wDest">he width, in logical units, of the source and destination rectangles</param>
/// <param name="hDest">The height, in logical units, of the source and the destination rectangles</param>
/// <param name="hdcSource">A handle to the source device context</param>
/// <param name="xSrc">The x-coordinate, in logical units, of the upper-left corner of the source rectangle</param>
/// <param name="ySrc">The y-coordinate, in logical units, of the upper-left corner of the source rectangle</param>
/// <param name="RasterOp">A raster-operation code. These codes define how the color data for the source rectangle is to be combined with the color data for the destination rectangle to achieve the final color</param>
/// <returns>If the function succeeds, the return value is nonzero</returns>
[DllImport("gdi32.dll")]
extern public static bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp);
/// <summary>
/// This function creates a bitmap compatible with the device associated with the specified device context
/// </summary>
/// <param name="hdc">Handle to a device context</param>
/// <param name="nWidth">Specifies the bitmap width, in pixels</param>
/// <param name="nHeight">Specifies the bitmap height, in pixels</param>
/// <returns>A handle to the bitmap indicates success. NULL indicates failure.</returns>
[DllImport("gdi32.dll")]
extern public static IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
/// <summary>
/// This function creates a memory device context (DC) compatible with the specified device
/// </summary>
/// <param name="hdc">Handle to an existing device context</param>
/// <returns>The handle to a memory device context indicates success. NULL indicates failure.</returns>
[DllImport("gdi32.dll")]
extern public static IntPtr CreateCompatibleDC(IntPtr hdc);
/// <summary>
///
/// </summary>
/// <param name="lpszDriver"></param>
/// <param name="passNULL"></param>
/// <param name="passNULL2"></param>
/// <param name="passNULL3"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
extern public static IntPtr CreateDC(string lpszDriver, IntPtr passNULL, IntPtr passNULL2, IntPtr passNULL3);
/// <summary>
///
/// </summary>
/// <param name="hDc"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
extern public static IntPtr DeleteDC(IntPtr hDc);
/// <summary>
///
/// </summary>
/// <param name="hDc"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
extern public static IntPtr DeleteObject(IntPtr hDc);
/// <summary>
///
/// </summary>
/// <param name="hdc"></param>
/// <param name="bmp"></param>
/// <returns></returns>
[DllImport("gdi32.dll")]
extern public static IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
}
}

Some files were not shown because too many files have changed in this diff Show More