initial checkin of yaulw (locally)
This commit is contained in:
37
.gitignore
vendored
Normal file
37
.gitignore
vendored
Normal 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
|
||||
70
@integrate/AlternateDataStreamWrapper.cs
Normal file
70
@integrate/AlternateDataStreamWrapper.cs
Normal 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
839
@integrate/App.xaml.cs
Normal 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
161
@integrate/AppState.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
311
@integrate/CMDlineHandler.cs
Normal file
311
@integrate/CMDlineHandler.cs
Normal 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] : ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
482
@integrate/CheckActiveTwo.cs
Normal file
482
@integrate/CheckActiveTwo.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
121
@integrate/ClickOnceUpdater.cs
Normal file
121
@integrate/ClickOnceUpdater.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
276
@integrate/Component.All/Common.cs
Normal file
276
@integrate/Component.All/Common.cs
Normal 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
|
||||
}
|
||||
}
|
||||
62
@integrate/Component.All/Common_MediLytec.cs
Normal file
62
@integrate/Component.All/Common_MediLytec.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
79
@integrate/Component.All/Component.All.csproj
Normal file
79
@integrate/Component.All/Component.All.csproj
Normal 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>
|
||||
223
@integrate/Component.All/ComponentConfig.cs
Normal file
223
@integrate/Component.All/ComponentConfig.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
277
@integrate/Component.All/Component_Binary_Manager.cs
Normal file
277
@integrate/Component.All/Component_Binary_Manager.cs
Normal 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
|
||||
}
|
||||
}
|
||||
213
@integrate/Component.All/Component_Setup_Manager.cs
Normal file
213
@integrate/Component.All/Component_Setup_Manager.cs
Normal 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
|
||||
}
|
||||
}
|
||||
13
@integrate/Component.All/EmbeddedComponentConfig.xml
Normal file
13
@integrate/Component.All/EmbeddedComponentConfig.xml
Normal 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>
|
||||
328
@integrate/Component.All/GenericInstaller.cs
Normal file
328
@integrate/Component.All/GenericInstaller.cs
Normal 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
|
||||
}
|
||||
}
|
||||
61
@integrate/Component.All/IInstallComponent.cs
Normal file
61
@integrate/Component.All/IInstallComponent.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
53
@integrate/Component.All/IManageComponents.cs
Normal file
53
@integrate/Component.All/IManageComponents.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
112
@integrate/Component.All/ISetup.cs
Normal file
112
@integrate/Component.All/ISetup.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
36
@integrate/Component.All/Properties/AssemblyInfo.cs
Normal file
36
@integrate/Component.All/Properties/AssemblyInfo.cs
Normal 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")]
|
||||
7
@integrate/HiddenMainWindow.xaml
Normal file
7
@integrate/HiddenMainWindow.xaml
Normal 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>
|
||||
1456
@integrate/HiddenMainWindow.xaml.cs
Normal file
1456
@integrate/HiddenMainWindow.xaml.cs
Normal file
File diff suppressed because it is too large
Load Diff
158
@integrate/InstallComponent.cs
Normal file
158
@integrate/InstallComponent.cs
Normal 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
|
||||
}
|
||||
}
|
||||
186
@integrate/InstallComponent2.cs
Normal file
186
@integrate/InstallComponent2.cs
Normal 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
|
||||
}
|
||||
}
|
||||
254
@integrate/InstallComponent4.cs
Normal file
254
@integrate/InstallComponent4.cs
Normal 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
240
@integrate/Logging.cs
Normal 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
482
@integrate/MsgBox.cs
Normal 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
12
@integrate/README.txt
Normal 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
120
@integrate/ResxHelper.cs
Normal 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
1057
@integrate/Settings.cs
Normal file
File diff suppressed because it is too large
Load Diff
24
@integrate/Snippets.txt
Normal file
24
@integrate/Snippets.txt
Normal 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
238
@integrate/SysTray.cs
Normal 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
140
@integrate/TTimer.cs
Normal 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
|
||||
}
|
||||
}
|
||||
654
@integrate/Trinet.Core.IO.Ntfs/AlternateDataStreamInfo.cs
Normal file
654
@integrate/Trinet.Core.IO.Ntfs/AlternateDataStreamInfo.cs
Normal 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
|
||||
}
|
||||
}
|
||||
32
@integrate/Trinet.Core.IO.Ntfs/FileStreamAttributes.cs
Normal file
32
@integrate/Trinet.Core.IO.Ntfs/FileStreamAttributes.cs
Normal 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,
|
||||
}
|
||||
}
|
||||
56
@integrate/Trinet.Core.IO.Ntfs/FileStreamType.cs
Normal file
56
@integrate/Trinet.Core.IO.Ntfs/FileStreamType.cs
Normal 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,
|
||||
}
|
||||
}
|
||||
452
@integrate/Trinet.Core.IO.Ntfs/FileSystem.cs
Normal file
452
@integrate/Trinet.Core.IO.Ntfs/FileSystem.cs
Normal 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
|
||||
}
|
||||
}
|
||||
118
@integrate/Trinet.Core.IO.Ntfs/SafeHGlobalHandle.cs
Normal file
118
@integrate/Trinet.Core.IO.Ntfs/SafeHGlobalHandle.cs
Normal 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
|
||||
}
|
||||
}
|
||||
478
@integrate/Trinet.Core.IO.Ntfs/SafeNativeMethods.cs
Normal file
478
@integrate/Trinet.Core.IO.Ntfs/SafeNativeMethods.cs
Normal 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
|
||||
}
|
||||
}
|
||||
134
@integrate/Trinet.Core.IO.Ntfs/StreamName.cs
Normal file
134
@integrate/Trinet.Core.IO.Ntfs/StreamName.cs
Normal 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
322
@integrate/WCFHost.cs
Normal 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
491
Assembly/AssemblyW.cs
Normal 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
|
||||
}
|
||||
}
|
||||
BIN
Components/ICSharpCode.SharpZipLib.dll
Normal file
BIN
Components/ICSharpCode.SharpZipLib.dll
Normal file
Binary file not shown.
BIN
Components/log4net.dll
Normal file
BIN
Components/log4net.dll
Normal file
Binary file not shown.
29
Encryption/TextEncryptHash.cs
Normal file
29
Encryption/TextEncryptHash.cs
Normal 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
287
File/CHMFile.cs
Normal 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
193
File/FileWriter.cs
Normal 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
213
File/INIFile.cs
Normal 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
185
File/ISReadWrite.cs
Normal 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
172
File/LineReplacer.cs
Normal 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
176
File/LoggerQuick.cs
Normal 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
391
File/Logging.cs
Normal 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
190
File/Tail.cs
Normal 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
344
Installer/Common.cs
Normal 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
249
Installer/FileIcon.cs
Normal 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
953
Installer/ShellLink.cs
Normal 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
1698
Monitor/MonitorDataStore.cs
Normal file
File diff suppressed because it is too large
Load Diff
177
Net/Emailer.cs
Normal file
177
Net/Emailer.cs
Normal 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
832
Net/IPHostHelper.cs
Normal 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
14
Net/RouterHelper.cs
Normal 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
73
Net/WCHelper.cs
Normal 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
292
Net/WSCaller.cs
Normal 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
423
Other/CMDLine.cs
Normal 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
102
Other/CMDcommands.cs
Normal 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
83
Other/CMDexecute.cs
Normal 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
|
||||
}
|
||||
}
|
||||
36
Other/DelegateCollection.cs
Normal file
36
Other/DelegateCollection.cs
Normal 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
43
Other/Installer.cs
Normal 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
116
Other/OSInfo.cs
Normal 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
57
Other/StackWalker.cs
Normal 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
255
Other/StateM.cs
Normal 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
78
Other/TraceM.cs
Normal 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
550
Other/Versioning.cs
Normal 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
110
Process/PStartInfo.cs
Normal 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
274
Process/PStarter.cs
Normal 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
309
Process/ProcessW.cs
Normal 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
212
Process/ServiceW.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal 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
487
Registry/RegKey.cs
Normal 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
35
Structs/sbstring.cs
Normal 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
507
Thread/DispatcherThread.cs
Normal 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
143
Thread/SingleThreadTimer.cs
Normal 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
140
Thread/TStarter.cs
Normal 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
143
Thread/TTimer.cs
Normal 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
162
Thread/TTimerDisp.cs
Normal 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
45
Tools/Convert.cs
Normal 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
143
Tools/EnumTool.cs
Normal 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
269
Tools/ObjTool.cs
Normal 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
259
Tools/PathNaming.cs
Normal 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
165
Tools/StringTool.cs
Normal 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
319
WPF/KeepHidden.cs
Normal 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
156
WPF/Snippets.cs
Normal 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
232
WPF/WPFWindowManager.cs
Normal 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
59
Web/HTTP.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Web/WebClientWithTimeout.cs
Normal file
43
Web/WebClientWithTimeout.cs
Normal 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
27
Win32/Advapi32.cs
Normal 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
321
Win32/AtomMessenger.cs
Normal 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
116
Win32/COM.cs
Normal 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
70
Win32/Convert.cs
Normal 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
601
Win32/Definitions.cs
Normal 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
388
Win32/Functions.cs
Normal 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
85
Win32/Gdi32.cs
Normal 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
Reference in New Issue
Block a user