Initial check-in

This commit is contained in:
Duc
2025-03-13 18:15:01 -07:00
parent 5303f6544a
commit 18e39145cc
43 changed files with 10801 additions and 20 deletions

63
.gitattributes vendored Normal file
View File

@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

377
.gitignore vendored
View File

@@ -1,26 +1,363 @@
# ---> Windows
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# Dump file
*.stackdump
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# Folder config file
[Dd]esktop.ini
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mono auto generated files
mono_crash.*
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Windows shortcuts
*.lnk
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

132
CommonLib/CommonLib.csproj Normal file
View File

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CommonLib</RootNamespace>
<AssemblyName>CommonLib</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.DirectoryServices" />
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Library\Collections\MultiMap.cs" />
<Compile Include="Library\Diagnostics\ProcessStarter.cs" />
<Compile Include="Library\Diagnostics\StopWatchCustom.cs" />
<Compile Include="Library\DirectoryServices\ActiveDirectory.cs" />
<Compile Include="Library\IO\FileManip.cs" />
<Compile Include="Library\IO\Hardware.cs" />
<Compile Include="Library\IO\IniFileManip.cs" />
<Compile Include="Library\IO\PathManip.cs" />
<Compile Include="Library\IO\TreeUtils.cs" />
<Compile Include="Library\Misc\ArrayManip.cs" />
<Compile Include="Library\Misc\Conversion.cs" />
<Compile Include="Library\Misc\DateTimeManip.cs" />
<Compile Include="Library\Misc\ErrorHandling.cs" />
<Compile Include="Library\Misc\StringManip.cs" />
<Compile Include="Library\Windows\Misc\NetworkManagement.cs" />
<Compile Include="Library\Windows\Misc\NetworkSharing.cs" />
<Compile Include="Library\Windows\Misc\WindowsAdministration.cs" />
<Compile Include="Library\Windows\Misc\WindowShortcut.cs" />
<Compile Include="Library\Runtime\InteropServices\Win32Helpers.cs" />
<Compile Include="Library\Windows\Forms\FormControlsFormatting.cs" />
<Compile Include="Library\Windows\Forms\FormControlsManipThreadSafe.cs" />
<Compile Include="Library\Windows\Forms\frmChildForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Library\Windows\Forms\frmChildForm.designer.cs">
<DependentUpon>frmChildForm.cs</DependentUpon>
</Compile>
<Compile Include="Library\Windows\Forms\MessageBoxCustom.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxEx.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExButton.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExButtons.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExIcon.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExManager.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExResult.cs" />
<Compile Include="Library\Windows\Forms\MessageBoxExLib\TimeoutResult.cs" />
<Compile Include="Library\Windows\Misc\WindowsRegistry.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Library\Net\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Library\Windows\Forms\MessageBoxExLib\MessageBoxExForm.resx">
<DependentUpon>MessageBoxExForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Library\Windows\Forms\MessageBoxExLib\Resources\StandardButtonsText.de.resx" />
<EmbeddedResource Include="Library\Windows\Forms\MessageBoxExLib\Resources\StandardButtonsText.fr.resx" />
<EmbeddedResource Include="Library\Windows\Forms\MessageBoxExLib\Resources\StandardButtonsText.resx" />
</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>

31
CommonLib/CommonLib.sln Normal file
View File

@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.34601.136
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonLib", "CommonLib.csproj", "{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Debug|x64.ActiveCfg = Debug|x64
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Debug|x64.Build.0 = Debug|x64
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Release|Any CPU.Build.0 = Release|Any CPU
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Release|x64.ActiveCfg = Release|x64
{C88B26CE-093C-475E-B8FA-E70BA5A0D16E}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BE528BB8-3FB5-4D7C-8534-C024B287B265}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,143 @@
///======================================================================================
/// File: MultiMap.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Provides MultiMap functionality
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace CommonLib.Collections
{
///======================================================================================
/// MultiMap
///======================================================================================
/// <summary>
/// This class defines a MultiMap where one can add multiple values to a
/// single key in a Dictionary. This code uses string keys
///
/// Usage example:
/// bool b1 = true;
/// bool b2 = false;
/// bool b3 = false;
///
/// MultiMap<bool> m1 = new MultiMap<bool>();
/// m1.Add("key1", b1);
/// m1.Add("key1", b2);
/// m1.Add("key2", b3);
///
/// foreach (string k in m1.Keys)
/// {
/// foreach (bool b in m1[k])
/// {
/// Console.WriteLine(k + "=" + b);
/// }
/// }
///
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
public class MultiMap<V>
{
// 1
Dictionary<string, List<V>> _dictionary = new Dictionary<string, List<V>>();
public int keyCount = 0;
///==========================================================================
/// MultiMap.Add
///==========================================================================
/// <summary>
/// Adds the specified value under the specified key. If key doesn't exist
/// yet, add the key and increment the key count
/// </summary>
/// <param name="key">a string key</param>
/// <param name="value">a string value associated with the key</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public void Add(string key, V value)
{
List<V> list;
if (this._dictionary.TryGetValue(key, out list))
{
// 2A.
list.Add(value);
}
else
{
// 2B.
list = new List<V>();
list.Add(value);
this._dictionary[key] = list;
keyCount++;
}
}
///==========================================================================
/// MultiMap.GetKeyValueCount
///==========================================================================
/// <summary>
/// For a specified key, return the number of entries associated with it
/// </summary>
/// <param name="key">a string key</param>
/// <param name="value">a string value associated with the key</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public int GetKeyValueCount(string key)
{
List<V> list;
if (this._dictionary.TryGetValue(key, out list))
{
return list.Count;
}
return 0;
}
// 3
public IEnumerable<string> Keys
{
get
{
return this._dictionary.Keys;
}
}
// 4
public List<V> this[string key]
{
get
{
List<V> list;
if (this._dictionary.TryGetValue(key, out list))
{
return list;
}
else
{
return new List<V>();
}
}
}
}
}

View File

@@ -0,0 +1,107 @@
///======================================================================================
/// File: clsProcessStarter.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Provides a class to start a process, get output message if any and exit code
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Diagnostics;
namespace CommonLib.Diagnostics
{
///======================================================================================
/// clsProcessStarter
///======================================================================================
/// <summary>
/// Provides a class to start a process, get output message if any and exit code
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
public class ProcessStarter
{
private ProcessStartInfo procInfo = null;
public int procExitCode
{
get;
set;
}
public string outputMsg
{
get;
set;
}
public string procArguments
{
get;
set;
}
public string fileName
{
get;
set;
}
public ProcessStarter()
{
procExitCode = -1;
outputMsg = "";
procArguments = "";
fileName = "";
}
///==========================================================================
/// clsProcessStarter.Run
///==========================================================================
/// <summary>
/// Run another process, save output message if any and exit code
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public void Run()
{
int exitCode = this.procExitCode;
try
{
procInfo = new ProcessStartInfo(this.fileName);
procInfo.RedirectStandardOutput = true;
procInfo.UseShellExecute = false;
procInfo.CreateNoWindow = true;
procInfo.Arguments = this.procArguments;
Process proc = Process.Start(procInfo);
this.outputMsg = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
exitCode = proc.ExitCode;
proc.Close();
}
catch
{
}
this.procExitCode = exitCode;
}
}
}

View File

@@ -0,0 +1,178 @@
///======================================================================================
/// File: StopWatchCustom.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// This is a custom Stopwatch with extra functionality since there's already a StopWatch
/// in Microsoft Libraries, but with limited functionality
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace CommonLib.Diagnostics
{
///======================================================================================
/// StopWatchCustom
///======================================================================================
/// <summary>
/// This class can return the elapsed time in multiple formats
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
public class StopWatchCustom
{
private DateTime startTime;
private DateTime stopTime;
private DateTime currentTime;
private bool running = false;
///==========================================================================
/// StopWatchCustom.Start
///==========================================================================
/// <summary>
/// Keeps track of the start time
/// </summary>
/// <param>None</param>
/// <return>void</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public void Start()
{
this.startTime = DateTime.Now;
this.running = true;
}
///==========================================================================
/// StopWatchCustom.Stop
///==========================================================================
/// <summary>
/// Keeps track of the stop time
/// </summary>
/// <param>None</param>
/// <return>void</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public void Stop()
{
this.stopTime = DateTime.Now;
this.running = false;
}
///==========================================================================
/// StopWatchCustom.GetElapsedTimeString
///==========================================================================
/// <summary>
/// Calculates elapsed time and format the time into days, hours, minutes
/// and seconds
/// </summary>
/// <param>None</param>
/// <return>a string indicating days, hours, minutes and seconds</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public string GetElapsedTimeString()
{
TimeSpan interval;
if (!running)
return ""; //interval = DateTime.Now - startTime;
else
{
this.currentTime = DateTime.Now;
interval = currentTime - startTime;
}
int days = interval.Days;
double hours = interval.Hours;
double mins = interval.Minutes;
double secs = interval.Seconds;
string x = "";
if (days != 0)
{
x += days.ToString() + ":";
}
if (hours != 0)
{
x += hours.ToString("00") + ":";
}
x += mins.ToString("00") + ":";
x += secs.ToString("00");
return x;
}
///==========================================================================
/// StopWatchCustom.GetElapsedMilliseconds
///==========================================================================
/// <summary>
/// Calculates elapsed time and return the time in milliseconds
/// </summary>
/// <param>None</param>
/// <return>time in milliseconds</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public double GetElapsedMilliseconds()
{
TimeSpan interval;
if (running)
interval = DateTime.Now - startTime;
else
interval = stopTime - startTime;
return interval.TotalMilliseconds;
}
///==========================================================================
/// StopWatchCustom.GetElapsedTimeSecs
///==========================================================================
/// <summary>
/// Calculates elapsed time and return the time in seconds
/// </summary>
/// <param>None</param>
/// <return>time in seconds</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public double GetElapsedTimeSecs()
{
TimeSpan interval;
if (running)
interval = DateTime.Now - startTime;
else
interval = stopTime - startTime;
return interval.TotalSeconds;
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
namespace CommonLib.DirectoryServices
{
public static class ActiveDirectoryQuery
{
public static LDAPSearchResult LDAPanonymousConnect(string LDAPserver, string LDAPpath)
{
LDAPSearchResult LDAPsearchMe = new LDAPSearchResult();
LDAPsearchMe.LDAPsearch = null;
// create and return new LDAP connection with desired settings
DirectoryEntry ldapConnection = new DirectoryEntry("LDAP://" + LDAPserver + "/" + LDAPpath);
ldapConnection.AuthenticationType = AuthenticationTypes.None;
try
{
// create search object which operates on LDAP connection object
// and set search object to only find the user specified
LDAPsearchMe.LDAPsearch = new DirectorySearcher(ldapConnection);
LDAPsearchMe.ConnectStatus = LDAPQueryResult.LDAPConnectSuccess;
}
catch (Exception e)
{
LDAPsearchMe.ErrorMsg = e.ToString();
LDAPsearchMe.ConnectStatus = LDAPQueryResult.LDAPConnectFailed;
}
return LDAPsearchMe;
}
public static LDAPSearchResult LDAPsecureConnect(string LDAPserver, string domain, string userName, string LDAPpassword, string LDAPpath)
{
LDAPSearchResult LDAPsearchMe = new LDAPSearchResult();
LDAPsearchMe.LDAPsearch = null;
// create and return new LDAP connection with desired settings
DirectoryEntry ldapConnection = new DirectoryEntry(LDAPserver);
ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
ldapConnection.Username = domain + @"\" + userName;
ldapConnection.Password = LDAPpassword;
ldapConnection.Path = LDAPpath;
try
{
// create search object which operates on LDAP connection object
// and set search object to only find the user specified
LDAPsearchMe.LDAPsearch = new DirectorySearcher(ldapConnection);
LDAPsearchMe.ConnectStatus = LDAPQueryResult.LDAPConnectSuccess;
}
catch (Exception e)
{
LDAPsearchMe.ErrorMsg = e.ToString();
LDAPsearchMe.ConnectStatus = LDAPQueryResult.LDAPConnectFailed;
}
return LDAPsearchMe;
}
public struct LDAPSearchResult
{
public string ErrorMsg
{
get;
set;
}
public LDAPQueryResult ConnectStatus
{
get;
set;
}
public DirectorySearcher LDAPsearch
{
get;
set;
}
}
public enum LDAPQueryResult
{
// Summary:
// If connection to LDAP is successful
LDAPConnectSuccess = 0,
//
// Summary:
// If connection to LDAP fails
LDAPConnectFailed = 1,
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.IO;
using CommonLib.Runtime.InteropServices;
namespace CommonLib.IO
{
public class Hardware
{
///==========================================================================
/// Hardware.GetAllCdDrives
///==========================================================================
/// <summary>
/// Get all the drive letters of all the cd drives in the computer
/// </summary>
/// <return>list of cd drive letters</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static List<string> GetAllCdDrives()
{
List<string> cdDrives = new List<string>();
foreach (var drive in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.CDRom))
{
cdDrives.Add(drive.Name);
}
return cdDrives;
}
///==========================================================================
/// Hardware.IsCdDrive
///==========================================================================
/// <summary>
/// Determine if drive letter is CD Drive
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool IsCdDrive(string driveLetter)
{
bool isCdRom = false;
string driveLetterFormatted = "";
Match regExMatch;
regExMatch = Regex.Match(driveLetter, @"([a-zA-Z]).*");
if (regExMatch.Success)
{
driveLetterFormatted = regExMatch.Groups[1].Value;
foreach (var drive in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.CDRom))
{
if (Regex.IsMatch(driveLetterFormatted + @":\", @"^" + Regex.Escape(drive.Name), RegexOptions.IgnoreCase))
{
isCdRom = true;
break;
}
}
}
return isCdRom;
}
///==========================================================================
/// Hardware.OpenCdDrive
///==========================================================================
/// <summary>
/// Open CD Drive
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool OpenCdDrive(string driveLetter)
{
const int OPEN_EXISTING = 3;
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const uint IOCTL_STORAGE_EJECT_MEDIA = 2967560;
const uint FILE_SHARE_READ = 0x00000001;
const uint FILE_SHARE_WRITE = 0x00000002;
bool successful = true;
Match regExMatch;
string driveLetterFormatted = "";
if (driveLetter.Length == 0)
successful = false;
if (successful)
{
regExMatch = Regex.Match(driveLetter, @"([a-zA-Z]).*");
if (regExMatch.Success)
{
driveLetterFormatted = regExMatch.Groups[1].Value;
}
if (IsCdDrive(driveLetterFormatted))
{
string path = "\\\\.\\" + driveLetterFormatted + ":";
IntPtr handle = Win32Helpers.CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero);
if ((long)handle != -1)
{
int dummy = 0;
Win32Helpers.DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0,
IntPtr.Zero, 0, ref dummy, IntPtr.Zero);
Win32Helpers.CloseHandle(handle);
}
}
else
successful = false;
}
return successful;
}
}
}

View File

@@ -0,0 +1,204 @@
///======================================================================================
/// File: IniFileManip.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Manipulate INI file
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using CommonLib.Misc;
namespace CommonLib.IO
{
///======================================================================================
/// IniFileManip
///======================================================================================
/// <summary>
/// This class can read, write or query any section, key and values in an INI file
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
public class IniFileManip
{
public string iniFile;
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,
string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section,
string key, string def, StringBuilder retVal, int size, string filePath);
[DllImport("kernel32")]
static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
uint nSize, string lpFileName);
[DllImport("kernel32")]
private static extern int GetPrivateProfileSection(string section, byte[] lpReturnedString, int nSize, string lpFileName);
public IniFileManip(string path)
{
iniFile = path;
}
///==========================================================================
/// IniFileManip.IniWriteValue
///==========================================================================
/// <summary>
/// Modify a value of a key in Ini file. If key doesn't exist, add it
/// </summary>
/// <param name="Section"></param>
/// <param name="Key"></param>
/// <param name="Value"></param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public void WriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, this.iniFile);
}
///==========================================================================
/// IniFileManip.IniReadValue
///==========================================================================
/// <summary>
/// Read a value of a key in Ini file
/// </summary>
/// <param name="Section"></param>
/// <param name="Key"></param>
/// <return>Value of a key in a section of the ini file</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public string ReadValue(string Section, string Key)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.iniFile);
return temp.ToString();
}
///==========================================================================
/// IniFileManip.SectionExists
///==========================================================================
/// <summary>
/// Determines if a section exist in Ini file
/// </summary>
/// <param name="Section"></param>
/// <return>true if a section exists, otherwise false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
public bool SectionExists(string Section)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, null, "", temp, 255, this.iniFile);
return (i > 0);
}
///==========================================================================
/// IniFileManip.getSectionNames
///==========================================================================
/// <summary>
/// Get names of all sections in the ini file, even duplicate section names
/// </summary>
/// <return>an array of strings with section names</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
public string[] GetSectionNames()
{
uint MAX_BUFFER = 32767;
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, iniFile);
if (bytesReturned == 0)
{
Marshal.FreeCoTaskMem(pReturnedString);
return null;
}
string local = Marshal.PtrToStringAnsi(pReturnedString, (int)bytesReturned).ToString();
Marshal.FreeCoTaskMem(pReturnedString);
//use of Substring below removes terminating null for split
return local.Substring(0, local.Length - 1).Split('\0');
}
///==========================================================================
/// IniFileManip.getUniqueSectionNames
///==========================================================================
/// <summary>
/// Get names of only unique sections in the ini file. If there are duplicate
/// section names, only 1 is chosen
/// </summary>
/// <return>an array of strings with unique section names</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
public string[] GetUniqueSectionNames()
{
uint MAX_BUFFER = 32767;
IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, iniFile);
if (bytesReturned == 0)
{
Marshal.FreeCoTaskMem(pReturnedString);
return null;
}
string local = Marshal.PtrToStringAnsi(pReturnedString, (int)bytesReturned).ToString();
Marshal.FreeCoTaskMem(pReturnedString);
return ArrayManip.GetDistinctValues(local.Substring(0, local.Length - 1).Split('\0'));
}
///==========================================================================
/// IniFileManip.readSectionData
///==========================================================================
/// <summary>
/// Get all the keys and their associated values in a section
/// </summary>
/// <param name="section"></param>
/// <return>an array of strings with each entry containing key and value pair
/// </return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
public string[] ReadSectionData(string section)
{
const int bufferSize = 32767;
StringBuilder returnedString = new StringBuilder();
byte[] pReturnedString = new byte[bufferSize];
GetPrivateProfileSection(section, pReturnedString, bufferSize, iniFile);
return Encoding.ASCII.GetString(pReturnedString).Trim('\0').Split('\0');
}
}
}

View File

@@ -0,0 +1,716 @@
///======================================================================================
/// File: PathManip.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// This class deals with anything having to do with directory and file paths
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.ComponentModel;
using CommonLib.Misc;
using CommonLib.Windows.Misc;
namespace CommonLib.IO
{
public class PathManip
{
[DllImport("shlwapi.dll")]
public static extern bool PathIsNetworkPath(string path);
[DllImport("Shlwapi.dll")]
public static extern bool PathIsUNC(String pszPath);
public enum enumWindowsDesignatedPaths { USER_DESKTOP, USER_PROFILE, ALL_USER_DESKTOP, USER_STARTUP_FOLDER, ALL_USER_STARTUP_FOLDER, USER_TEMP_FOLDER, CD_DRIVE };
///==========================================================================
/// PathManip.PathIsFile
///==========================================================================
/// <summary>
/// Determine if a given path is a file
/// </summary>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool PathIsFile(string path)
{
bool isFile = false;
if (File.Exists(path))
isFile = true;
else if (Regex.IsMatch(path, @".+\.[^\\//.]+$", RegexOptions.IgnoreCase))
{
isFile = true;
}
return isFile;
}
///==========================================================================
/// PathManip.IsAbsolutePath
///==========================================================================
/// <summary>
/// Determine if a given path is an absolute path
/// </summary>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool IsAbsolutePath(string path)
{
bool pathIsAbsolute = false;
if (Regex.IsMatch(path, @"^(?:[a-zA-Z]\:|\\\\[\w\.]+\\[\w.$]+)\\(?:[\w]+\\)*\w([\w.])+$"))
{
pathIsAbsolute = true;
}
return pathIsAbsolute;
}
///==========================================================================
/// PathManip.GetUserDesktopPath
///==========================================================================
/// <summary>
/// Get the path to the user desktop
/// </summary>
/// <return>User's desktop path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetUserDesktopPath()
{
string path = "";
// get the full domain and logon id
string currentWindowLogin = WindowsAdministration.GetWindowLoginID();
// get only logon id
currentWindowLogin = Regex.Replace(currentWindowLogin, @"[^\\]+\\([^\\]+)", "$1");
path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// if this application is run as an account other than the account used to log into windows
if (!Regex.IsMatch(path, currentWindowLogin))
{
// Modify the desktop path to reflect the desktop path of the actual account used to log into windows
path = Regex.Replace(path, @"(.+)\\[^\\]+\\Desktop", "$1\\" + currentWindowLogin + "\\Desktop", RegexOptions.IgnoreCase);
}
path = RemoveTrailingSlashInPath(path);
return path;
}
///==========================================================================
/// PathManip.GetUserProfilePath
///==========================================================================
/// <summary>
/// Get the path to user's home directory
/// </summary>
/// <return>User's desktop path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetUserProfilePath()
{
string path = "";
path = RemoveTrailingSlashInPath(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
return path;
}
///==========================================================================
/// PathManip.GetAllUserDesktopPath
///==========================================================================
/// <summary>
/// Get the path to the all user's desktop
/// </summary>
/// <return>User's desktop path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetAllUserDesktopPath()
{
string path = "";
path = RemoveTrailingSlashInPath(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory));
return path;
}
///==========================================================================
/// PathManip.GetUserStartupFolderPath
///==========================================================================
/// <summary>
/// Get the path to the user startup folder
/// </summary>
/// <return>User's desktop path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetUserStartupFolderPath()
{
string path = "";
// get the full domain and logon id
string currentWindowLogin = WindowsAdministration.GetWindowLoginID();
// get only logon id
currentWindowLogin = Regex.Replace(currentWindowLogin, @"[^\\]+\\([^\\]+)", "$1");
path = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
// if this application is run as an account other than the account used to log into windows
if (!Regex.IsMatch(path, currentWindowLogin))
{
// Modify the desktop path to reflect the desktop path of the actual account used to log into windows
path = Regex.Replace(path, @"(.+\\Users\\)[^\\]+(\\.+Start Menu)", "${1}" + currentWindowLogin + "$2", RegexOptions.IgnoreCase);
}
path = RemoveTrailingSlashInPath(path);
return path;
}
///==========================================================================
/// PathManip.GetAllUserStartupFolderPath
///==========================================================================
/// <summary>
/// Get the path to the all user startup folder
/// </summary>
/// <return>User's desktop path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetAllUserStartupFolderPath()
{
string path = "";
path = RemoveTrailingSlashInPath(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartup));
return path;
}
///==========================================================================
/// PathManip.GetUserTempPath
///==========================================================================
/// <summary>
/// Get the path to the user's temporary folder
/// </summary>
/// <return>User's temporary path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetUserTempPath()
{
string path = "";
// get the full domain and logon id
string currentWindowLogin = WindowsAdministration.GetWindowLoginID();
// get only logon id
currentWindowLogin = Regex.Replace(currentWindowLogin, @"[^\\]+\\([^\\]+)", "$1");
path = Path.GetTempPath();
// if this application is run as an account other than the account used to log into windows
if (!Regex.IsMatch(path, currentWindowLogin))
{
// Modify the desktop path to reflect the desktop path of the actual account used to log into windows
path = Regex.Replace(path, @"(.+)\\[^\\]+\\(appdata.+[^\\])\\?", "$1\\" + currentWindowLogin + "\\$2", RegexOptions.IgnoreCase);
}
path = RemoveTrailingSlashInPath(path);
return path;
}
///==========================================================================
/// PathManip.DeleteFoldersRecursive
///==========================================================================
/// <summary>
/// Delete folder including all file and subfolders within it
/// </summary>
/// <param name="directory">Path to a directory</param>
/// <return>None</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static void DeleteFoldersRecursive(string directory)
{
var dirInfo = new DirectoryInfo(directory) { Attributes = FileAttributes.Normal };
foreach (var info in dirInfo.GetFileSystemInfos("*", SearchOption.AllDirectories))
{
info.Attributes = FileAttributes.Normal;
}
dirInfo.Delete(true);
}
///==========================================================================
/// PathManip.PathIsWritable
///==========================================================================
/// <summary>
/// Given a path, make sure we can create a folder if it doesn't exist
/// or if it does exist, create an empty file in it to see if user has write
/// access
/// </summary>
/// <param name="path">Path to a directory</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool PathIsWritable(string path)
{
bool writable = true;
path = PathManip.AddTrailingSlashToPath(path);
// if the path doesn't exist and it contains at least one folder,
// we want to check if upper level folder exists
if (!Directory.Exists(path) && PathContainsAtLeastOneFolder(path))
{
string tempDir = "";
string topLevelDirNotFound = path;
while (!Directory.Exists(topLevelDirNotFound))
{
if (!Regex.IsMatch(topLevelDirNotFound, @"[^\\]+\\", RegexOptions.IgnoreCase))
{
writable = false;
break;
}
tempDir = topLevelDirNotFound;
// remove the inner most folder
topLevelDirNotFound = Regex.Replace(topLevelDirNotFound, @"\\[^\\]+\\?$", "", RegexOptions.IgnoreCase);
}
if (writable)
{
if (tempDir.Length > 0)
topLevelDirNotFound = tempDir;
else
tempDir = path;
try
{
Directory.CreateDirectory(path);
// delete only the directories that were created
Directory.Delete(tempDir, true);
}
catch
{
writable = false;
}
}
}
else // if the path exists
{
string filename = "test";
string fileExt = ".txt";
int count = 1;
string errMsg = "";
string filePathAndName = Path.Combine(path, filename + fileExt);
while (File.Exists(filePathAndName))
{
filename = "test" + (count++).ToString();
filePathAndName = Path.Combine(path, filename + fileExt);
}
// create a new file
if (!FileManip.CopyFile("", "", Path.GetDirectoryName(filePathAndName), Path.GetFileName(filePathAndName), true, FileAttributes.Normal, ref errMsg))
writable = false;
else
File.Delete(filePathAndName);
}
return writable;
}
///==========================================================================
/// PathManip.GenerateUniquePath
///==========================================================================
/// <summary>
/// Generate a unique path
/// Example: C:\path -> C:\path_07252015_R1
/// </summary>
/// <param name="path">Path to a directory</param>
/// <return>Unique path</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GenerateUniquePath(string path)
{
int logCount = 0;
string logDir;
string sLogCount = "00";
DateTime dt = DateTime.Now;
string strYear = dt.ToString("yy");
string strMonth = dt.ToString("MM");
string strDay = dt.ToString("dd");
while (true)
{
logDir = Path.GetFullPath(path);
logDir += "_" + strMonth + strDay + strYear + "_R" + sLogCount;
logCount++;
if (Directory.Exists(logDir))
{
if (logCount < 10)
{
sLogCount = "0" + logCount.ToString();
}
else
sLogCount = logCount.ToString();
}
else
break;
}
return logDir;
}
///==========================================================================
/// PathManip.PathContainsAtLeastOneFolder
///==========================================================================
/// <summary>
/// Given a path, indicate whether the path contains at least one folder
/// </summary>
/// <param name="path">Path to a directory</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool PathContainsAtLeastOneFolder(string path)
{
bool pathContainsFolders = false;
if (Regex.IsMatch(path, @"([a-zA-Z]):\\[^\\]+", RegexOptions.IgnoreCase)
||
Regex.IsMatch(path, @"(\\\\[^\\]+)\\[^\\]+", RegexOptions.IgnoreCase)
)
{
pathContainsFolders = true;
}
return pathContainsFolders;
}
///==========================================================================
/// PathManip.GetDriveLetterOrHostnameFromPath
///==========================================================================
/// <summary>
/// Given a path, return the drive letter if the path is a local path or
/// host name if the path is network path
/// </summary>
/// <param name="path">Path to a directory</param>
/// <return>drive letter or hostname</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetDriveLetterOrHostnameFromPath(string path)
{
string driveLetterOrHostname = "";
if (PathIsNetworkPath(path))
{
Uri bb = new Uri(path);
driveLetterOrHostname = bb.Host;
}
else
{
Match regExMatch = Regex.Match(path, @"([a-zA-Z]):.*", RegexOptions.IgnoreCase);
if (regExMatch.Success)
driveLetterOrHostname = regExMatch.Groups[1].Value;
}
return driveLetterOrHostname;
}
///==========================================================================
/// PathManip.DirectoryVisible
///==========================================================================
/// <summary>
/// Check to see if Directory is there even though user has no access to it
/// This is the case where the directory exists, but user has no access to
/// it so the call Directory.Exists() would fail making us think that the
/// directory doesn't exist when in fact it does
/// </summary>
/// <param name="path">Path to a directory</param>
/// <param name="errMsg">error message</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool DirectoryVisible(string path, ref string errMsg)
{
bool successful = true;
try
{
Directory.GetAccessControl(path);
}
catch (UnauthorizedAccessException)
{
errMsg = "The account used by this application does not have required permission to access directory " + path;
}
catch (Exception e)
{
int errorCode = 0;
if (ErrorHandling.GetExceptionErrorCode(e.Message, ref errorCode))
{
if (errorCode == 1326)
errMsg = "Error code " + errorCode.ToString() + " - Logon Failure. The account used by this application is not permitted to access directory " + path;
else
successful = false;
}
else
{
errMsg = "Unknown error occurred";
successful = false;
}
}
return successful;
}
///==========================================================================
/// PathManip.PathIsLocalPath
///==========================================================================
/// <summary>
/// Given a path (either UNC or local path), determine if the path is local path
/// </summary>
/// <param name="path">path</param>
/// <return>true/false</return>
///==========================================================================
public static bool PathIsLocalPath(string path)
{
bool isLocalPath = true;
if (!PathIsUNC(path))
{
isLocalPath = !PathIsNetworkPath(path);
}
else
{
Uri uri = new Uri(path);
isLocalPath = HostIsLocal(uri.Host); // Refer to David's answer
}
return isLocalPath;
}
///==========================================================================
/// PathManip.HostIsLocal
///==========================================================================
/// <summary>
/// Given a hostname, determine if it is a local hostname
/// </summary>
/// <param name="hostname">hostname</param>
/// <return>true/false</return>
///==========================================================================
public static bool HostIsLocal(string hostname)
{
IPAddress[] host;
//get host addresses
try { host = Dns.GetHostAddresses(hostname); }
catch (Exception) { return false; }
//get local adresses
IPAddress[] local = Dns.GetHostAddresses(Dns.GetHostName());
//check if local
return host.Any(hostAddress => IPAddress.IsLoopback(hostAddress) || local.Contains(hostAddress));
}
///==========================================================================
/// PathManip.GetProperFilePathCapitalization
///==========================================================================
/// <summary>
/// Takes a file path along with the file name and return the exact
/// case-lettering of directory name and file name as they are named
/// in the Windows file system
/// </summary>
/// <param name="filePathAndName">File name along with its path</param>
/// <return>Same path and file name as the path passed in as a parameter
/// except the path and file name has the exact case lettering as how they
/// are named in the Windows file system
/// </return>
///==========================================================================
public static string GetProperFilePathCapitalization(string filePathAndName)
{
string path = filePathAndName;
if (File.Exists(filePathAndName))
{
FileInfo fileInfo = new FileInfo(filePathAndName);
DirectoryInfo dirInfo = fileInfo.Directory;
string dir = GetProperDirectoryCapitalization(dirInfo.FullName);
string file = dirInfo.GetFiles(fileInfo.Name)[0].Name;
// if the path is a UNC path, the GetProperDirectoryCapitalization() will
// only return the path without the hostname, we must then extract the hostname
// then prepend it to the path
if (PathIsUNC(filePathAndName))
{
Uri bb = new Uri(filePathAndName);
dir = @"\\" + bb.Host + @"\" + dir;
}
path = Path.Combine(dir, file);
}
return path;
}
///==========================================================================
/// PathManip.GetProperDirectoryCapitalization
///==========================================================================
/// <summary>
/// Takes a directory path and return the exact case-lettering of
/// directory name as they are named in the Windows file system
/// </summary>
/// <param name="path">Path to a directory</param>
/// <return>Same path as the path passed in as a parameter except the
/// path has the exact case lettering as how they are named in the Windows
/// file system
/// </return>
///==========================================================================
public static string GetProperDirectoryCapitalization(string path)
{
string dir = path;
if (Directory.Exists(path))
{
DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectoryInfo parentDirInfo = dirInfo.Parent;
if (null == parentDirInfo)
return dirInfo.Name;
dir = Path.Combine(GetProperDirectoryCapitalization(parentDirInfo.FullName), parentDirInfo.GetDirectories(dirInfo.Name)[0].Name);
}
return dir;
}
///==========================================================================
/// PathManip.AddTrailingSlashToPath
///==========================================================================
/// <summary>
/// Add trailing slash at the end of a directory path if there's none
/// </summary>
/// <param name="path">path to directory</param>
/// <return>Path without the slash at the end</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string AddTrailingSlashToPath(string path)
{
return Regex.Replace(path, @"(.+[^\\/])$", "$1\\");
}
///==========================================================================
/// PathManip.RemoveTrailingSlashInPath
///==========================================================================
/// <summary>
/// Remove trailing slash at the end of a directory path if it exists
/// </summary>
/// <param name="path">path to directory</param>
/// <return>Path without the slash at the end</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string RemoveTrailingSlashInPath(string path)
{
return Regex.Replace(path, @"(\\+|/+)$", "");
}
///==========================================================================
/// PathManip.RemoveLeadingSlashInPath
///==========================================================================
/// <summary>
/// Remove leading slash at the beginning of a directory path if it exists
/// </summary>
/// <param name="path">path to directory</param>
/// <return>Path without the slash at the front</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string RemoveLeadingSlashInPath(string path)
{
return Regex.Replace(path, @"^(\\+|/+)", "");
}
///==========================================================================
/// PathManip.PathsEqual
///==========================================================================
/// <summary>
/// Compare if 2 paths are equal
/// </summary>
/// <param name="path1">path 1</param>
/// <param name="path2">path 2</param>
/// <param name="caseSensitivity">case sensitivity</param>
/// <return>true if 2 paths are equal, otherwise false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool PathsEqual(string path1, string path2, StringComparison caseSensitivity)
{
string path1WithoutSlashes = Regex.Replace(path1, @"[\\/]", ",");
string path2WithoutSlashes = Regex.Replace(path2, @"[\\/]", ",");
if (string.Equals(path1WithoutSlashes, path2WithoutSlashes, caseSensitivity))
return true;
else
return false;
}
}
}

View File

@@ -0,0 +1,169 @@
//===========================================================================================
// TreeUtils.cs
//===========================================================================================
// GENERAL DESCRIPTION OR PURPOSE:
// Generic C# Tree utility
//
//===========================================================================================
// Date Programmer Proj. SAR / STRIP Description
// -------- ---------- ---------- ----------- -----------------------------------------
// 06/29/12 J.Weichers SSIRU-742X 1448 Initial Version
//===========================================================================================
using System;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows.Forms;
namespace CommonLib.IO
{
public class TreeUtils
{
static private bool DEBUG = false;
private string m_treeRoot = "";
///===================================================================================
/// TreeUtils::TreeUtils
///===================================================================================
/// <summary>
/// Class Ctor for TreeUtils
/// </summary>
/// <param name="treeRoot">String that specifies the tree's root directory</param>
///===================================================================================
/// Date Programmer Proj.ID SAR / STRIP Description
/// --/--/-- ---------- ---------- ------------- ----------------------------------
/// 06/12/12 J.Weichers SSIRU-742X 1448 Original
///===================================================================================
public TreeUtils(string treeRoot)
{
m_treeRoot = treeRoot;
}
///===================================================================================
/// TreeUtils::DeleteFileSystemInfo
///===================================================================================
/// <summary>
/// Delete a file, or folder and any files or sub-folders if necessary
/// </summary>
/// <param name="fsi">A file or a directory</param>
///===================================================================================
/// Date Programmer Proj.ID SAR / STRIP Description
/// --/--/-- ---------- ---------- ------------- ----------------------------------
/// 06/12/12 J.Weichers SSIRU-742X 1448 Original
///===================================================================================
public static void DeleteFileSystemInfo(FileSystemInfo fsi)
{
fsi.Attributes = FileAttributes.Normal;
var di = fsi as DirectoryInfo;
if (di != null)
{
foreach (var dirInfo in di.GetFileSystemInfos())
{
DeleteFileSystemInfo(dirInfo);
}
}
fsi.Delete();
}
///===================================================================================
/// TreeUtils::TreeCopy
///===================================================================================
/// <summary>
/// Recursive function to copy a tree from one location to another. The Directory.Move()
/// has a recursive option, but is buggy, and throws random exceptions. It also is
/// limited
/// </summary>
/// <param name="srcFolderPath">A directory that has a sub-directory to be copied</param>
/// <param name="srcFolderName">The name of the direcory to be copied</param>
/// <param name="destFolderPath">A destination directory of the copy</param>
///===================================================================================
/// Date Programmer Proj.ID SAR / STRIP Description
/// --/--/-- ---------- ---------- ------------- ----------------------------------
/// 06/12/12 J.Weichers SSIRU-742X 1448 Original
///===================================================================================
static public void TreeCopy(String srcFolderPath, // folder and path to copy
String srcFolderName, // folder to copy
String destFolderPath) // where to copy to
{
try
{
DirectoryInfo srcDirInfo = new
DirectoryInfo(srcFolderPath + "\\");
// 1. Create the new destination directory
String newDestFolder = Path.Combine(destFolderPath, srcFolderName);
try
{
Directory.CreateDirectory(newDestFolder);
}
catch (Exception Exc)
{
MessageBox.Show("Error creating directory '" + newDestFolder +
"': " + Exc.Message, "Directory Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
// 2. copy the files first
FileInfo[] fileInfoArray = srcDirInfo.GetFiles();
foreach (FileInfo file in fileInfoArray)
{
String newFileAndPath = Path.Combine(newDestFolder, file.Name);
try
{
file.CopyTo(newFileAndPath, true);
}
catch (Exception Exc)
{
MessageBox.Show("Error copying file '" + file.Name + "': " +
Exc.Message, "File Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
// 3. copy the sub-directories last via recursion
DirectoryInfo[] dirInfoArray = srcDirInfo.GetDirectories();
foreach (DirectoryInfo di in dirInfoArray)
{
TreeCopy(Path.Combine(srcFolderPath, di.Name),
di.Name,
Path.Combine(destFolderPath, srcFolderName));
}
}
catch (Exception Exc) { ExceptionMessageBox(Exc, Environment.StackTrace); }
}
///===================================================================================
/// TreeUtils::ExceptionMessageBox
///===================================================================================
/// <summary>
/// Convenience exception utility
/// </summary>
/// <param name="Exc">The exception that was thrown</param>
/// <param name="stack">The call stack when the exception was thrown</param>
///===================================================================================
/// Date Programmer Proj.ID SAR / STRIP Description
/// --/--/-- ---------- ---------- ------------- ----------------------------------
/// 06/12/12 J.Weichers SSIRU-742X 1448 Original
///===================================================================================
static public void ExceptionMessageBox(Exception Exc, String stack)
{
if (DEBUG == true)
{
MessageBox.Show(Exc.ToString() + "\nStack trace: " +
stack, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
MessageBox.Show(Exc.ToString(), "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}

View File

@@ -0,0 +1,63 @@
///======================================================================================
/// File: ArrayManip.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Manipulate arrays
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace CommonLib.Misc
{
///==========================================================================
/// ArrayManip
///==========================================================================
/// <summary>
/// Manipulate arrays
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class ArrayManip
{
///==========================================================================
/// ArrayManip.GetDistinctValues
///==========================================================================
/// <summary>
/// Given an array of any type, return an array of the same type with only
/// unique values
/// </summary>
/// <param name="array">an array of any type</param>
/// <return>an array of any type with only unique values</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public T[] GetDistinctValues<T>(T[] array)
{
List<T> tmp = new List<T>();
for (int i = 0; i < array.Length; i++)
{
if (tmp.Contains(array[i]))
continue;
tmp.Add(array[i]);
}
return tmp.ToArray();
}
}
}

View File

@@ -0,0 +1,73 @@
///======================================================================================
/// File: Conversion.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Perform various conversions
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace CommonLib.Misc
{
///==========================================================================
/// Conversion
///==========================================================================
/// <summary>
/// Perform various conversions
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class Conversion
{
///==========================================================================
/// Conversion.UInt32ToIP
///==========================================================================
/// <summary>
/// Convert an octet (8bit) of type UInt32 to a string representation
/// </summary>
/// <param name="ipAddress">an octet of type UInt32</param>
/// <returns>an octet of type string</returns>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public string UInt32ToIP(UInt32 ipAddress)
{
return new IPAddress(BitConverter.GetBytes(ipAddress).Reverse().ToArray()).ToString();
}
///==========================================================================
/// Conversion.IP2UInt32
///==========================================================================
/// <summary>
/// Convert an octet (8bit) of type string to type UInt32 representation
/// </summary>
/// <param name="ipAddress">an octet of type string</param>
/// <returns>an octet of type UInt32</returns>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
public static UInt32 IP2UInt32(string ipAddress)
{
return BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(), 0);
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using System.Xml;
using System.Xml.XPath;
using CommonLib.Windows.Forms;
using CommonLib.IO;
using CommonLib.Misc;
using CommonLib.DirectoryServices;
using Assembly = System.Reflection.Assembly;
namespace CommonLib.Misc
{
public static class DateTimeManip
{
///===================================================================================
/// DateTimeManip.DescribeTimeElapsed
///===================================================================================
/// <summary>
/// Give a variable of type TimeSpan, describe the time in days, hours, mins, seconds
/// </summary>
/// <param name="TimeSpan">use the stopwatch.elapsed</param>
///===================================================================================
/// Date Programmer Proj.ID SAR / STRIP Description
/// --/--/-- ---------- ---------- ------------- ----------------------------------
/// 05/29/12 D.Le
///===================================================================================
public static string DescribeTimeElapsed(TimeSpan ts)
{
string describe = "";
if (ts.Days > 0)
describe += ts.Days.ToString() + " d";
if (ts.Hours > 0)
{
if (describe.Length > 0)
describe += " ";
describe += ts.Hours.ToString() + " h";
}
if (ts.Minutes > 0)
{
if (describe.Length > 0)
describe += " ";
describe += ts.Minutes.ToString() + " m";
}
if (ts.Seconds > 0)
{
if (describe.Length > 0)
describe += " ";
describe += ts.Seconds.ToString() + " s";
}
if (describe.Length == 0)
describe = "0 s";
return describe;
}
///===================================================================================
/// DateTimeManip.GetLinkerDateTime
///===================================================================================
/// <summary>
/// Get the date and time of when the assembly was built by reading its PE information
/// Usage: Assembly.GetExecutingAssembly().GetLinkerDateTime()
/// </summary>
/// <param name="TimeSpan">use the stopwatch.elapsed</param>
///===================================================================================
/// Date Programmer Proj.ID TEMA Description
/// --/--/-- ---------- ---------- ------------- ----------------------------------
/// 05/29/12 D.Le
///===================================================================================
public static DateTime GetLinkerDateTime(this Assembly assembly, TimeZoneInfo tzi = null)
{
// Constants related to the Windows PE file format.
const int PE_HEADER_OFFSET = 60;
const int LINKER_TIMESTAMP_OFFSET = 8;
// Discover the base memory address where our assembly is loaded
var entryModule = assembly.ManifestModule;
var hMod = Marshal.GetHINSTANCE(entryModule);
if (hMod == IntPtr.Zero - 1) throw new Exception("Failed to get HINSTANCE.");
// Read the linker timestamp
var offset = Marshal.ReadInt32(hMod, PE_HEADER_OFFSET);
var secondsSince1970 = Marshal.ReadInt32(hMod, offset + LINKER_TIMESTAMP_OFFSET);
// Convert the timestamp to a DateTime
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var linkTimeUtc = epoch.AddSeconds(secondsSince1970);
var dt = TimeZoneInfo.ConvertTimeFromUtc(linkTimeUtc, tzi ?? TimeZoneInfo.Local);
return dt;
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace CommonLib.Misc
{
public class ErrorHandling
{
///==========================================================================
/// Misc.ErrorHandling
///==========================================================================
/// <summary>
/// Get error code from the error message
/// </summary>
/// <param name="errorMsg">error message</param>
/// <param name="errorCode">error code returned</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool GetExceptionErrorCode(string errorMsg, ref int errorCode)
{
bool successful = true;
Match regExMatch;
regExMatch = Regex.Match(errorMsg, @".+ error code ([\d]+)[^d]+", RegexOptions.IgnoreCase);
if (regExMatch.Success)
{
errorCode = Convert.ToInt32(regExMatch.Groups[1].Value);
}
else
successful = false;
return successful;
}
}
}

View File

@@ -0,0 +1,193 @@
///======================================================================================
/// File: ArrayManip.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Manipulate string
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace CommonLib.Misc
{
public class StringManip
{
public enum enumTextHorizontalAlignment
{
Left,
Right
}
///==========================================================================
/// StringManip.IsValidIPv4
///==========================================================================
/// <summary>
/// Given an IP version 4 address. Determine if it is valid or not
/// </summary>
/// <param name="ipString">IP Address</param>
/// <returns>true/false</returns>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool IsValidIPv4(string ipString)
{
if (String.IsNullOrWhiteSpace(ipString))
{
return false;
}
string[] splitValues = ipString.Split('.');
if (splitValues.Length != 4)
{
return false;
}
byte tempForParsing;
return splitValues.All(r => byte.TryParse(r, out tempForParsing));
}
///==========================================================================
/// StringManip.GetPhraseWordIndexInText
///==========================================================================
/// <summary>
/// Return the word index of the first word of the phrase in a string
/// </summary>
/// <param name="text">a string</param>
/// <param name="phrase">a phrase to look for in the text</param>
/// <returns>index</returns>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static int GetPhraseWordIndexInText(string text, string phrase)
{
int index = -1;
int matchIndex = -1;
Regex ItemRegex = new Regex(@"\s*[^\s]+", RegexOptions.Compiled);
string[] wordsInPhrase = phrase.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
string wordBuilder = "";
if (wordsInPhrase.Length > 0)
{
// going through each word in text
foreach (Match ItemMatch in ItemRegex.Matches(text))
{
index++;
if (wordBuilder.Length > 0)
wordBuilder += " ";
wordBuilder += ItemMatch.ToString().Trim();
string[] wordsInWordBuilder = wordBuilder.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (wordsInWordBuilder.Length == wordsInPhrase.Length)
{
if (String.Equals(wordBuilder, phrase, StringComparison.OrdinalIgnoreCase))
{
matchIndex = index - (wordsInPhrase.Length - 1);
break;
}
else
{
wordBuilder = "";
for (int i = 1; i < wordsInPhrase.Length; i++)
{
if (wordBuilder.Length > 0)
wordBuilder += " ";
wordBuilder += wordsInWordBuilder[i];
}
}
}
}
}
return matchIndex;
}
///==========================================================================
/// StringManip.ShortenStringToSize
///==========================================================================
/// <summary>
/// Given a string and a desired string length, if the actual string's length
/// is greater than the desired string length, we keep only the left-most and
/// the right-most parts of the string.
/// the size of the left-most part of the string will be (Desired String Length / 2)
/// the size of the right-most part of the string will be (Desired String Length / 2)
/// </summary>
/// <param name="str"></param>
/// <param name="desiredStrLen"></param>
/// <returns>a string</returns>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
static public string ShortenStringToSize(string str, int desiredStrLen)
{
string shortenString = str;
if (str.Length > desiredStrLen && str.Length >= 5)
{
int leftCharCount = (int)Math.Ceiling((desiredStrLen - 3.0) / 2.0);
int rightCharCount = desiredStrLen - 3 - leftCharCount;
shortenString = str.Substring(0, leftCharCount) + "..." + str.Substring(str.Length - rightCharCount, rightCharCount);
}
return shortenString;
}
///==========================================================================
/// TextAlign
///==========================================================================
/// <summary>
/// Align text to left-aligned or right-aligned given the maximum number
/// of characters. If maximum of characters is bigger than the length of
/// the text provided, space will be padded to make up the difference
/// </summary>
/// <param name="text">a string</param>
/// <param name="maxNumCharacters"></param>
/// <param name="horizonAlignmentPos"></param>
/// <returns>a string</returns>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
static public string TextAlign(string text, int maxNumCharacters, enumTextHorizontalAlignment horizonAlignmentPos)
{
string str = text;
string padding = "";
int diff = maxNumCharacters - text.Length;
for (int i = 1; i <= diff; i++)
{
padding += " ";
}
if (horizonAlignmentPos == enumTextHorizontalAlignment.Left)
str += padding;
else
str = padding + str;
return str;
}
}
}

View File

@@ -0,0 +1,112 @@
///======================================================================================
/// File: DocumentFormat.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Formatting form controls that display text
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le SSIRU_PL 1448 Original
///======================================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace Northgrum.Runtime.InteropServices
{
///==========================================================================
/// FileManip
///==========================================================================
/// <summary>
/// Format any form control that display text in it
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le SSIRU_PL 1448 Original
///==========================================================================
public class DocumentFormat
{
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref PARAFORMAT lParam);
const int PFM_SPACEBEFORE = 0x00000040;
const int PFM_SPACEAFTER = 0x00000080;
const int PFM_LINESPACING = 0x00000100;
const int SCF_SELECTION = 1;
const int EM_SETPARAFORMAT = 1095;
///==========================================================================
/// DocumentFormat.setLineFormatInRichTextBox
///==========================================================================
/// <summary>
/// Allow the setting of line spacing in RichTextBox
///
/// For rule, there are only 6 possible values, 0-5
/// 0 - Single Spacing, line spacing is ignored
/// 1 - One-and-a-half spacing. line spacing is ignored
/// 2 - Double spacing. line spacing is ignored
/// 3 - Line spacing specifies spacing from one line to the next
/// 4 - Line spacing specifies spacing from one line to the next
/// 5 - Line spacing/20 is the spacing from one line to the next
/// </summary>
/// <param name="rTextbox">rich text box control</param>
/// <param name="rule">can only be 0-5 (the summary describes each rule)</param>
/// <param name="space">amount of spacing between 2 lines</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le SSIRU_PL 1448 Original
///==========================================================================
static public void setLineFormatInRichTextBox(RichTextBox rTextbox, byte rule, int space)
{
PARAFORMAT fmt = new PARAFORMAT();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = PFM_LINESPACING;
fmt.dyLineSpacing = space;
fmt.bLineSpacingRule = rule;
rTextbox.SelectAll();
SendMessage(new HandleRef(rTextbox, rTextbox.Handle), EM_SETPARAFORMAT, SCF_SELECTION, ref fmt);
}
[StructLayout(LayoutKind.Sequential)]
public struct PARAFORMAT
{
public int cbSize;
public uint dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
// PARAFORMAT2 from here onwards
public int dySpaceBefore;
public int dySpaceAfter;
public int dyLineSpacing;
public short sStyle;
public byte bLineSpacingRule;
public byte bOutlineLevel;
public short wShadingWeight;
public short wShadingStyle;
public short wNumberingStart;
public short wNumberingStyle;
public short wNumberingTab;
public short wBorderSpace;
public short wBorderWidth;
public short wBorders;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
namespace CommonLib.Windows.Forms
{
///==========================================================================
/// TextFormatting
///==========================================================================
/// <summary>
/// Primary purpose is to define the format of text such as text font and color
/// mainly for display in rich text box
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class TextFormat
{
// this struct define the text formatting of a selected number of words in a string
// must define word index and word count, word index starts at 0
public struct TextFontAndColor
{
public int wordIndex;
public int wordCount;
public Font textFont;
public Color textColor;
public TextFontAndColor(Font fontProp, Color fontColor, int textWordIndex = -1, int textWordCount = -1)
{
wordIndex = textWordIndex;
wordCount = textWordCount;
textFont = fontProp;
textColor = fontColor;
}
public TextFontAndColor(string nothing)
{
wordIndex = -1;
wordCount = -1;
textFont = new Font("Microsoft Sans Serif", 9, FontStyle.Regular);
textColor = Color.Black;
}
}
}
///==========================================================================
/// FormatRichTextBox
///==========================================================================
/// <summary>
/// Format rich text box
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class FormatRichTextBox
{
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, ref PARAFORMAT lParam);
const int PFM_SPACEBEFORE = 0x00000040;
const int PFM_SPACEAFTER = 0x00000080;
const int PFM_LINESPACING = 0x00000100;
const int SCF_SELECTION = 1;
const int EM_SETPARAFORMAT = 1095;
///==========================================================================
/// FormatRichTextBox.setLineFormat
///==========================================================================
/// <summary>
/// Allow the setting of line spacing in RichTextBox
///
/// For rule, there are only 6 possible values, 0-5
/// 0 - Single Spacing, line spacing is ignored
/// 1 - One-and-a-half spacing. line spacing is ignored
/// 2 - Double spacing. line spacing is ignored
/// 3 - Line spacing specifies spacing from one line to the next
/// 4 - Line spacing specifies spacing from one line to the next
/// 5 - Line spacing/20 is the spacing from one line to the next
/// </summary>
/// <param name="rTextbox">rich text box control</param>
/// <param name="rule">can only be 0-5 (the summary describes each rule)</param>
/// <param name="space">amount of spacing between 2 lines</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void setLineFormat(RichTextBox rTextbox, byte rule, int space)
{
PARAFORMAT fmt = new PARAFORMAT();
fmt.cbSize = Marshal.SizeOf(fmt);
fmt.dwMask = PFM_LINESPACING;
fmt.dyLineSpacing = space;
fmt.bLineSpacingRule = rule;
rTextbox.SelectAll();
SendMessage(new HandleRef(rTextbox, rTextbox.Handle), EM_SETPARAFORMAT, SCF_SELECTION, ref fmt);
}
[StructLayout(LayoutKind.Sequential)]
public struct PARAFORMAT
{
public int cbSize;
public uint dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
// PARAFORMAT2 from here onwards
public int dySpaceBefore;
public int dySpaceAfter;
public int dyLineSpacing;
public short sStyle;
public byte bLineSpacingRule;
public byte bOutlineLevel;
public short wShadingWeight;
public short wShadingStyle;
public short wNumberingStart;
public short wNumberingStyle;
public short wNumberingTab;
public short wBorderSpace;
public short wBorderWidth;
public short wBorders;
}
}
}

View File

@@ -0,0 +1,741 @@
///======================================================================================
/// File: FormControlsManipThreadSafe.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Provide a mechanism so that the main thread(main form) or its backgroundworker can
/// manipulate controls in a container
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Text.RegularExpressions;
namespace CommonLib.Windows.Forms
{
///==========================================================================
/// FormControlsManipThreadSafe
///==========================================================================
/// <summary>
/// This class allows backgroundworker(child threads) to manipulate controls
/// in a container
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class FormControlsManipThreadSafe
{
public enum ControlVisibility { Display, Hidden };
///==========================================================================
/// FormControlsManipThreadSafe.AddControlToContainer
///==========================================================================
/// <summary>
/// Add a control to a container(form, panel, etc)
/// </summary>
/// <param name="control">any form control</param>
/// <param name="container">a container control (form, panel, groupbox,
/// tabcontrol, etc)</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void AddControlToContainer(Control control, Control container)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (container.InvokeRequired)
{
container.Invoke(new Action(() => AddControlToContainer(control, container)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
container.Controls.Add(control);
}
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyLabelToDisplayWithinContainerVisibleWidth
///==========================================================================
/// <summary>
/// If the text in a label is too long and it goes past the boundary of the
/// container, want to shorten it so that it ends at the boundary of the
/// container. 3 periods will be inserted in the middle of the text of the
/// label to indicate that text were cut off in the middle
/// </summary>
/// <param name="control">a label or linklabel control</param>
/// <param name="widthOfContainingPanel">the width of the container in which
/// the control is located</param>
/// <param name="d_rightMargin">the right margin of the control's text with
/// respect to the container in which it is located</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void ModifyLabelToDisplayWithinContainerVisibleWidth(Control control, int widthOfContainingPanel, int d_rightMargin)
{
int minimumTextLength = 10, minimumWidthOfContainingPanel = 150;
int rightMargin = 2;
string connector = "...";
bool controlTextOverrunsVisibleLine = false;
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => ModifyLabelToDisplayWithinContainerVisibleWidth(control, widthOfContainingPanel, d_rightMargin)));
}
else
{
// only perform this for LinkLabel and Label types
if (control.GetType() != typeof(LinkLabel) && control.GetType() != typeof(Label))
return;
if (control.Text.Length < minimumTextLength || widthOfContainingPanel < minimumWidthOfContainingPanel)
return;
if (d_rightMargin > rightMargin)
rightMargin = d_rightMargin;
string text = control.Text;
Size textsize = TextRenderer.MeasureText(text, control.Font);
int maxTextLength = widthOfContainingPanel - control.Left - rightMargin;
string left = text.Substring(0, (int)Math.Floor(text.Length / 2.0));
string right = text.Substring(left.Length, (int)Math.Ceiling(text.Length / 2.0));
while (textsize.Width > maxTextLength)
{
if (!controlTextOverrunsVisibleLine)
controlTextOverrunsVisibleLine = true;
if (left.Length >= right.Length)
left = left.Substring(0, left.Length - 1);
else
right = right.Substring(1, right.Length - 1);
string newText = left + connector + right;
textsize = TextRenderer.MeasureText(newText, control.Font);
}
if (controlTextOverrunsVisibleLine)
control.Text = left + connector + right;
}
}
///==========================================================================
/// FormControlsManipThreadSafe.RemoveControlFromContainer
///==========================================================================
/// <summary>
/// Remove a control from a container(form, panel, etc)
/// </summary>
/// <param name="control">any form control</param>
/// <param name="container">a container control (form, panel, groupbox,
/// tabcontrol, etc)</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void RemoveControlFromContainer(Control control, Control container)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (container.InvokeRequired)
{
container.Invoke(new Action(() => RemoveControlFromContainer(control, container)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
container.Controls.Remove(control);
}
}
///==========================================================================
/// FormControlsManipThreadSafe.BaseClassObjectIsOfASpecificType
///==========================================================================
/// <summary>
/// Given any class object, usually of type base class, determine if the object
/// is of a specific type
/// </summary>
/// <param name="ojb">an object</param>
/// <param name="objectSpecificType">a type</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public bool BaseClassObjectIsOfASpecificType(object obj, Type objectSpecificType)
{
if (obj.GetType().IsAssignableFrom(objectSpecificType))
return true;
else
return false;
}
///==========================================================================
/// FormControlsManipThreadSafe.RemoveControlFromContainer
///==========================================================================
/// <summary>
/// Resize a container (form, panel, groupbox, etc)
/// </summary>
/// <param name="container">a container control (form, panel, groupbox,
/// tabcontrol, etc)</param>
/// <param name="resizeWidth">width to resize to</param>
/// <param name="resizeHeight">height to resize to</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void ResizeContainer(Control container, int resizeWidth, int resizeHeight)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (container.InvokeRequired)
{
container.Invoke(new Action(() => ResizeContainer(container, resizeWidth, resizeHeight)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
container.Width = resizeWidth;
container.Height = resizeHeight;
}
}
///==========================================================================
/// FormControlsManipThreadSafe.PositionControl
///==========================================================================
/// <summary>
/// Position a control within a container (form, panel, groupbox, etc)
/// </summary>
/// <param name="control">any form control</param>
/// <param name="pos">a Point object with X and Y position defined</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void PositionControl(Control control, Point pos)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => PositionControl(control, pos)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
control.Location = new System.Drawing.Point(pos.X, pos.Y);
}
}
///==========================================================================
/// FormControlsManipThreadSafe.SetControlVisibility
///==========================================================================
/// <summary>
/// Hide or Show a control on in the container
/// </summary>
/// <param name="control">any form control</param>
/// <param name="visibility">Enum type</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void SetControlVisibility(Control control, ControlVisibility visibility)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => SetControlVisibility(control, visibility)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
if (visibility == ControlVisibility.Display)
control.Visible = true;
else
control.Visible = false;
}
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyControlText
///==========================================================================
/// <summary>
/// Modify the text of a control
/// </summary>
/// <param name="control">any form control</param>
/// <param name="text">a string</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void ModifyControlText(Control control, string text)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => ModifyControlText(control, text)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
if (BaseClassObjectIsOfASpecificType(control, typeof(TextBox))
||
BaseClassObjectIsOfASpecificType(control, typeof(Button)))
control.Text = text;
else if (BaseClassObjectIsOfASpecificType(control, typeof(RichTextBox)))
{
RichTextBox rTextBox = control as RichTextBox;
rTextBox.AppendText(text);
}
}
}
///==========================================================================
/// FormControlsManipThreadSafe.RichTextBoxEraseLine
///==========================================================================
/// <summary>
/// Erase a paritcular line in Rich Text Box with the option to delete the
/// line completely.
/// Erase is just erasing all the characters on a line, but the line still
/// exists. If DeleteLine option is true, the whole line will be removed
/// </summary>
/// <param name="control">rich text box control</param>
/// <param name="lineIndex">line index, starting at index 0</param>
/// /// <param name="deleteLine">deleteLine</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void RichTextBoxEraseLine(RichTextBox control, int lineIndex, bool deleteLine)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => RichTextBoxEraseLine(control, lineIndex, deleteLine)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
int LineCharStartIndex;
int LineCharEndIndex;
int numCharsToBeRemove;
if (lineIndex >= 0 && lineIndex < control.Lines.Count())
{
LineCharStartIndex = control.GetFirstCharIndexFromLine(lineIndex);
if (control.Lines.Count() > (lineIndex + 1))
LineCharEndIndex = control.GetFirstCharIndexFromLine(lineIndex + 1) - 1;
else
LineCharEndIndex = control.TextLength;
numCharsToBeRemove = LineCharEndIndex - LineCharStartIndex;
if (numCharsToBeRemove > 0)
{
control.Select(LineCharStartIndex, numCharsToBeRemove);
control.SelectedText = "";
if (deleteLine)
{
if (lineIndex > 0 && control.Lines.Count() > 1)
{
// remove the line, this just means that we just shifted all the lines
// below this line up 1 line. The last line is empty
LineCharStartIndex = control.GetFirstCharIndexFromLine(lineIndex) - 1;
control.Select(LineCharStartIndex, 1);
control.SelectedText = "";
}
else if (lineIndex == 0 && control.Lines.Count() > 1)
{
// remove the line, this just means that we just shfited all the lines
// below this line up 1 line. The last line is empty
LineCharStartIndex = control.GetFirstCharIndexFromLine(lineIndex);
control.Select(LineCharStartIndex, 1);
control.SelectedText = "";
}
}
}
else if (lineIndex <= control.Lines.Count() - 1) // remove blank line
{
if (deleteLine)
{
if (lineIndex > 0)
{
control.Select(control.GetFirstCharIndexFromLine(lineIndex) - 1, 1);
}
else
{
control.Select(control.GetFirstCharIndexFromLine(lineIndex), 1);
}
control.SelectedText = "";
}
}
}
}
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyRichTextBoxText
///==========================================================================
/// <summary>
/// Modify the text of a rich text box in only 1 color
/// </summary>
/// <param name="control">rich text box control</param>
/// <param name="text">a string</param>
/// <param name="fontProp">font properties</param>
/// <param name="textColor">color property</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void ModifyRichTextBoxText(RichTextBox control, string text, Font fontProp, Color textColor)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => ModifyRichTextBoxText(control, text, fontProp, textColor)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
control.SelectionFont = fontProp;
control.SelectionColor = textColor;
control.AppendText(text);
}
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyRichTextBoxTextAtLine
///==========================================================================
/// <summary>
/// Modify the text of a rich text box in only 1 color at a particular line
/// starting a particular character index on that line
/// </summary>
/// <param name="control">rich text box control</param>
/// <param name="lineIndex">line index of the text box starting at 0</param>
/// <param name="charsCount">number of characters that have already been processed</param>
/// <param name="text">a string</param>
/// <param name="fontProp">font properties</param>
/// <param name="textColor">color property</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public bool ModifyRichTextBoxTextAtLine(RichTextBox control, int lineIndex, int charsCount, string word, Font fontProp, Color textColor)
{
bool success = true;
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
return (bool)control.Invoke(new Func<bool>(
delegate
{
return ModifyRichTextBoxTextAtLine(control, lineIndex, charsCount, word, fontProp, textColor);
}
));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
if (lineIndex < control.Lines.Count())
{
// determine the starting index of the new word
int startCharIndex = control.GetFirstCharIndexFromLine(lineIndex) + charsCount;
control.Select(startCharIndex, word.Length);
control.SelectionFont = fontProp;
control.SelectionColor = textColor;
control.SelectedText = control.SelectedText;
}
else
success = false;
return success;
}
}
///==========================================================================
/// FormControlsManipThreadSafe.getRichTextBoxLastLineIndex
///==========================================================================
/// <summary>
/// Modify text in rich text box in various colors and font at a particular
/// line
/// </summary>
/// <param name="control">rich text box control</param>
/// <param name="lineIndex">line index of the text box starting at 0</param>
/// <param name="textPropList">contains font properties for particular words</param>
/// <param name="defaultFont">the default font for words that are not defined in textPropList</param>
/// <param name="defaultFontColor">the default font color for words that are not defined in textPropList</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public int getRichTextBoxLastLineIndex(RichTextBox control)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
return (int)control.Invoke(new Func<int>(
delegate
{
return getRichTextBoxLastLineIndex(control);
}
));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
return (control.Lines.Count() - 1);
}
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyRichTextBoxPerWordsAtLine
///==========================================================================
/// <summary>
/// Modify text in rich text box in various colors and font at a particular
/// line
/// </summary>
/// <param name="control">rich text box control</param>
/// <param name="lineIndex">line index of the text box starting at 0</param>
/// <param name="textPropList">contains font properties for particular words</param>
/// <param name="defaultFont">the default font for words that are not defined in textPropList</param>
/// <param name="defaultFontColor">the default font color for words that are not defined in textPropList</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public bool ModifyRichTextBoxPerWordsAtLine(RichTextBox control, int lineIndex, string text, List<TextFormat.TextFontAndColor> textPropList, Font defaultFont, Color defaultFontColor)
{
int wordIndex = 0;
int wordCount = 0;
int textPropListIndex = -1;
Regex ItemRegex = new Regex(@"\s*[^ ]+", RegexOptions.Compiled);
bool success = true;
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
return (bool)control.Invoke(new Func<bool>(
delegate
{
return ModifyRichTextBoxPerWordsAtLine(control, lineIndex, text, textPropList, defaultFont, defaultFontColor);
}
));
}
else
{
if (lineIndex < control.Lines.Count())
{
int startCharIndex = control.GetFirstCharIndexFromLine(lineIndex);
int endCharIndex = lineIndex < control.Lines.Count() - 1 ?
control.GetFirstCharIndexFromLine(lineIndex + 1) - 1 :
control.Text.Length;
// select the whole line
control.Select(startCharIndex, endCharIndex - startCharIndex);
control.SelectionFont = defaultFont;
control.SelectionColor = defaultFontColor;
// replace line with new text
control.SelectedText = text;
// number of characters in all the words that have been processed
int charsProcessed = 0;
foreach (Match ItemMatch in ItemRegex.Matches(text))
{
if (wordCount == 0)
textPropListIndex = getTextPropListIndexForWordIndex(textPropList, wordIndex);
if ((textPropListIndex >= 0 && wordIndex == textPropList[textPropListIndex].wordIndex) || wordCount > 0)
{
if (wordCount == 0)
wordCount = textPropList[textPropListIndex].wordCount;
FormControlsManipThreadSafe.ModifyRichTextBoxTextAtLine(control, lineIndex, charsProcessed, ItemMatch.ToString(), textPropList[textPropListIndex].textFont, textPropList[textPropListIndex].textColor);
wordCount--;
if (wordCount == 0)
{
textPropList.RemoveAt(textPropListIndex);
}
}
else
{
FormControlsManipThreadSafe.ModifyRichTextBoxTextAtLine(control, lineIndex, charsProcessed, ItemMatch.ToString(), defaultFont, defaultFontColor);
}
wordIndex++;
charsProcessed += ItemMatch.ToString().Length;
}
if (textPropList != null)
textPropList.Clear();
Match regExMatch;
regExMatch = Regex.Match(text, @"[^ ]?( +)$");
// if there are spaces at the end of text, want to display it
if (regExMatch.Success)
{
FormControlsManipThreadSafe.ModifyRichTextBoxTextAtLine(control, lineIndex, charsProcessed, regExMatch.Groups[1].Value, defaultFont, defaultFontColor);
}
}
else
success = false;
return success;
}
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyRichTextBoxPerWords
///==========================================================================
/// <summary>
/// Modify text in rich text box in various colors and font
/// </summary>
/// <param name="control">rich text box control</param>
/// <param name="textPropList">contains font properties for particular words</param>
/// <param name="defaultFont">the default font for words that are not defined in textPropList</param>
/// <param name="defaultFontColor">the default font color for words that are not defined in textPropList</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void ModifyRichTextBoxPerWords(RichTextBox control, string text, List<TextFormat.TextFontAndColor> textPropList, Font defaultFont, Color defaultFontColor)
{
int wordIndex = 0;
int wordCount = 0;
int textPropListIndex = -1;
Regex ItemRegex = new Regex(@"\s*[^ ]+", RegexOptions.Compiled);
foreach (Match ItemMatch in ItemRegex.Matches(text))
{
if (wordCount == 0)
textPropListIndex = getTextPropListIndexForWordIndex(textPropList, wordIndex);
if ((textPropListIndex >= 0 && wordIndex == textPropList[textPropListIndex].wordIndex) || wordCount > 0)
{
if (wordCount == 0)
wordCount = textPropList[textPropListIndex].wordCount;
FormControlsManipThreadSafe.ModifyRichTextBoxText(control, ItemMatch.ToString(), textPropList[textPropListIndex].textFont, textPropList[textPropListIndex].textColor);
wordCount--;
if (wordCount == 0)
{
textPropList.RemoveAt(textPropListIndex);
}
}
else
{
FormControlsManipThreadSafe.ModifyRichTextBoxText(control, ItemMatch.ToString(), defaultFont, defaultFontColor);
}
wordIndex++;
}
if ( textPropList != null )
textPropList.Clear();
Match regExMatch;
regExMatch = Regex.Match(text, @"[^ ]?( +)$");
// if there are spaces at the end of text, want to display it
if (regExMatch.Success)
{
FormControlsManipThreadSafe.ModifyControlText(control, regExMatch.Groups[1].Value);
}
}
///==========================================================================
/// FormControlsManipThreadSafe.getTextPropListIndexForWordIndex
///==========================================================================
/// <summary>
/// textPropList contains a list of font properties of various words in a string
/// want to find the font property of a word or words starting at a particular word index
/// in the string
/// </summary>
/// <param name="textPropList">contains font properties for particular words</param>
/// <param name="wordIndex">index of the word in a string</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static private int getTextPropListIndexForWordIndex(List<TextFormat.TextFontAndColor> textPropList, int wordIndex)
{
int index = -1;
if (textPropList != null)
{
for (int i = 0; i < textPropList.Count; i++)
{
if (textPropList[i].wordIndex == wordIndex)
index = i;
}
}
return index;
}
///==========================================================================
/// FormControlsManipThreadSafe.ModifyControlColors
///==========================================================================
/// <summary>
/// Modify back color and fore color of a control
/// </summary>
/// <param name="control">any form control</param>
/// <param name="text">a string</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 06/06/12 D.Le
///==========================================================================
static public void ModifyControlColors(Control control, Color backColor, Color foreColor)
{
// when a different thread trying to access the value this control on a form that was created by another thread
if (control.InvokeRequired)
{
control.Invoke(new Action(() => ModifyControlColors(control, backColor, foreColor)));
}
// when the thread tries to access the value of the control on the form that belongs to the same thread
else
{
if (backColor != null)
control.BackColor = backColor;
if (foreColor != null)
control.ForeColor = foreColor;
}
}
}
}

View File

@@ -0,0 +1,190 @@
///======================================================================================
/// File: MessageBoxCustom.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// Provides an advanced message box with custom buttons and timeout
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace CommonLib.Windows.Forms
{
///==========================================================================
/// clsCustomButton
///==========================================================================
/// <summary>
/// This class defines a custom message box with custom buttons and timeout
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class MessageBoxCustom
{
public enum PopUpMsgType
{
// Summary:
// Indicates this is a error message to display with an OK button
ERROR = 0,
//
// Summary:
// Indicates this is just a info message with an OK button
INFO = 1,
// Summary:
// Indicates this is a pre-defined question and needs answer from user, 2 buttons
YESNO = 2,
// Summary:
// Indicates this is a pre-defined question and needs answer from user, 2 buttons
OKCANCEL = 3,
// Summary:
// Indicates this is a custom question and needs answer from user, buttons must be defined also
CUSTOMQUESTION = 4,
}
///==========================================================================
/// MessageBoxCustom.Show
///==========================================================================
/// <summary>
/// Displays a message box at the center of the calling parent form if it exists
/// </summary>
/// <param name="parentForm">the parent form that calls this message box.
/// If parent form doesn't exist, pass in null pointer
/// </param>
/// <param name="msgType">type of message (error,warning,info,custom,etc)</param>
/// <param name="customButtons">a list of custom buttons if the msgType
/// is custom, otherwise pass in null pointer
/// </param>
/// <param name="msg">The message to be display on the message box</param>
/// <param name="caption">The caption to be display at the top of
/// the message box
/// </param>
/// <param name="timeOut_ms">Specify timeout in milliseconds before
/// the message box will be automatically be closed. If timeout is not desired,
/// specify 0
/// </param>
/// <return>The value of the button that was pressed</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string Show(Form parentForm, PopUpMsgType msgType, List<clsCustomButton> customButtons, string msg, string caption, int timeOut_ms)
{
string result;
MessageBoxEx msgBox;
// create and customize an error message box
msgBox = MessageBoxExManager.CreateMessageBox(parentForm, "MsgBox");
msgBox.Font = new Font("Tahoma", 10);
switch (msgType)
{
case PopUpMsgType.ERROR:
msgBox.AddButtons(MessageBoxButtons.OK);
msgBox.Icon = (MessageBoxExIcon)MessageBoxIcon.Error;
//msgBox.SaveResponseText = "Don't ask me again";
break;
case PopUpMsgType.INFO:
msgBox.AddButtons(MessageBoxButtons.OK);
msgBox.Icon = (MessageBoxExIcon)MessageBoxIcon.Information;
//msgBox.SaveResponseText = "Don't ask me again";
break;
case PopUpMsgType.YESNO:
msgBox.AddButtons(MessageBoxButtons.YesNo);
msgBox.Icon = (MessageBoxExIcon)MessageBoxIcon.Question;
//msgBox.SaveResponseText = "Don't ask me again";
break;
case PopUpMsgType.OKCANCEL:
msgBox.AddButtons(MessageBoxButtons.OKCancel);
msgBox.Icon = (MessageBoxExIcon)MessageBoxIcon.Information;
//msgBox.SaveResponseText = "Don't ask me again";
break;
case PopUpMsgType.CUSTOMQUESTION:
if (customButtons != null && customButtons.Count > 1)
{
foreach (clsCustomButton button in customButtons)
{
msgBox.AddButton(button.buttonText, button.buttonValue);
}
msgBox.Icon = (MessageBoxExIcon)MessageBoxIcon.Question;
}
else
{
msgBox.AddButtons(MessageBoxButtons.OK);
msgBox.Icon = (MessageBoxExIcon)MessageBoxIcon.Error;
msg = "Custom question requires customized buttons with text and value for each button.\nPlease define the buttons and try again!";
}
//msgBox.SaveResponseText = "Don't ask me again";
break;
default:
break;
}
msgBox.Caption = caption;
msgBox.Text = msg;
if (timeOut_ms > 0)
{
msgBox.Timeout = timeOut_ms;
msgBox.TimeoutResult = TimeoutResult.Default;
}
result = msgBox.Show();
// if the message box was closed by a defined timeout
// must put in a delay so we can delete the messagebox instance
if (timeOut_ms > 0)
Thread.Sleep(500);
MessageBoxExManager.DeleteMessageBox("MsgBox");
msgBox = null;
return result;
}
///==========================================================================
/// clsCustomButton
///==========================================================================
/// <summary>
/// This class defines a custom button with text and value
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public class clsCustomButton
{
public string buttonText;
public string buttonValue;
public clsCustomButton()
{
buttonText = "";
buttonValue = "";
}
public clsCustomButton(string d_buttonText, string d_buttonValue)
{
buttonText = d_buttonText;
buttonValue = d_buttonValue;
}
}
}
}

View File

@@ -0,0 +1,311 @@
///======================================================================================
/// File: MessageBoxEx.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// An extended MessageBox with lot of customizing capabilities
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// An extended MessageBox with lot of customizing capabilities.
/// </summary>
public class MessageBoxEx
{
#region Fields
private MessageBoxExForm _msgBox;
private bool _useSavedResponse = true;
private string _name = null;
#endregion
#region Properties
internal string Name
{
get{ return _name; }
set{ _name = value; }
}
/// <summary>
/// Sets the caption of the message box
/// </summary>
public string Caption
{
set{_msgBox.Caption = value;}
}
/// <summary>
/// Sets the text of the message box
/// </summary>
public string Text
{
set{_msgBox.Message = value;}
}
/// <summary>
/// Sets the icon to show in the message box
/// </summary>
public Icon CustomIcon
{
set{_msgBox.CustomIcon = value;}
}
/// <summary>
/// Sets the icon to show in the message box
/// </summary>
public MessageBoxExIcon Icon
{
set{ _msgBox.StandardIcon = (MessageBoxIcon)Enum.Parse(typeof(MessageBoxIcon), value.ToString());}
}
/// <summary>
/// Sets the font for the text of the message box
/// </summary>
public Font Font
{
set{_msgBox.Font = value;}
}
/// <summary>
/// Sets or Gets the ability of the user to save his/her response
/// </summary>
public bool AllowSaveResponse
{
get{ return _msgBox.AllowSaveResponse; }
set{ _msgBox.AllowSaveResponse = value; }
}
/// <summary>
/// Sets the text to show to the user when saving his/her response
/// </summary>
public string SaveResponseText
{
set{_msgBox.SaveResponseText = value; }
}
/// <summary>
/// Sets or Gets whether the saved response if available should be used
/// </summary>
public bool UseSavedResponse
{
get{ return _useSavedResponse; }
set{ _useSavedResponse = value; }
}
/// <summary>
/// Sets or Gets whether an alert sound is played while showing the message box.
/// The sound played depends on the the Icon selected for the message box
/// </summary>
public bool PlayAlsertSound
{
get{ return _msgBox.PlayAlertSound; }
set{ _msgBox.PlayAlertSound = value; }
}
/// <summary>
/// Sets or Gets the time in milliseconds for which the message box is displayed.
/// </summary>
public int Timeout
{
get{ return _msgBox.Timeout; }
set{ _msgBox.Timeout = value; }
}
/// <summary>
/// Controls the result that will be returned when the message box times out.
/// </summary>
public TimeoutResult TimeoutResult
{
get{ return _msgBox.TimeoutResult; }
set{ _msgBox.TimeoutResult = value; }
}
#endregion
#region Methods
/// <summary>
/// Shows the message box
/// </summary>
/// <returns></returns>
public string Show()
{
return Show(null);
}
/// <summary>
/// Shows the messsage box with the specified owner
/// </summary>
/// <param name="owner"></param>
/// <returns></returns>
public string Show(IWin32Window owner)
{
if(_useSavedResponse && this.Name != null)
{
string savedResponse = MessageBoxExManager.GetSavedResponse(this);
if( savedResponse != null)
return savedResponse;
}
if(owner == null)
{
_msgBox.ShowDialog();
}
else
{
_msgBox.ShowDialog(owner);
}
if(this.Name != null)
{
if(_msgBox.AllowSaveResponse && _msgBox.SaveResponse)
MessageBoxExManager.SetSavedResponse(this, _msgBox.Result);
else
MessageBoxExManager.ResetSavedResponse(this.Name);
}
else
{
Dispose();
}
return _msgBox.Result;
}
/// <summary>
/// Add a custom button to the message box
/// </summary>
/// <param name="button">The button to add</param>
public void AddButton(MessageBoxExButton button)
{
if(button == null)
throw new ArgumentNullException("button","A null button cannot be added");
_msgBox.Buttons.Add(button);
if(button.IsCancelButton)
{
_msgBox.CustomCancelButton = button;
}
}
/// <summary>
/// Add a custom button to the message box
/// </summary>
/// <param name="text">The text of the button</param>
/// <param name="val">The return value in case this button is clicked</param>
public void AddButton(string text, string val)
{
if(text == null)
throw new ArgumentNullException("text","Text of a button cannot be null");
if(val == null)
throw new ArgumentNullException("val","Value of a button cannot be null");
MessageBoxExButton button = new MessageBoxExButton();
button.Text = text;
button.Value = val;
AddButton(button);
}
/// <summary>
/// Add a standard button to the message box
/// </summary>
/// <param name="buttons">The standard button to add</param>
public void AddButton(MessageBoxExButtons button)
{
string buttonText = MessageBoxExManager.GetLocalizedString(button.ToString());
if(buttonText == null)
{
buttonText = button.ToString();
}
string buttonVal = button.ToString();
MessageBoxExButton btn = new MessageBoxExButton();
btn.Text = buttonText;
btn.Value = buttonVal;
if(button == MessageBoxExButtons.Cancel)
{
btn.IsCancelButton = true;
}
AddButton(btn);
}
/// <summary>
/// Add standard buttons to the message box.
/// </summary>
/// <param name="buttons">The standard buttons to add</param>
public void AddButtons(MessageBoxButtons buttons)
{
switch(buttons)
{
case MessageBoxButtons.OK:
AddButton(MessageBoxExButtons.Ok);
break;
case MessageBoxButtons.AbortRetryIgnore:
AddButton(MessageBoxExButtons.Abort);
AddButton(MessageBoxExButtons.Retry);
AddButton(MessageBoxExButtons.Ignore);
break;
case MessageBoxButtons.OKCancel:
AddButton(MessageBoxExButtons.Ok);
AddButton(MessageBoxExButtons.Cancel);
break;
case MessageBoxButtons.RetryCancel:
AddButton(MessageBoxExButtons.Retry);
AddButton(MessageBoxExButtons.Cancel);
break;
case MessageBoxButtons.YesNo:
AddButton(MessageBoxExButtons.Yes);
AddButton(MessageBoxExButtons.No);
break;
case MessageBoxButtons.YesNoCancel:
AddButton(MessageBoxExButtons.Yes);
AddButton(MessageBoxExButtons.No);
AddButton(MessageBoxExButtons.Cancel);
break;
}
}
#endregion
#region Ctor
/// <summary>
/// Ctor is internal because this can only be created by MBManager
/// </summary>
internal MessageBoxEx()
{
_msgBox = new MessageBoxExForm(null);
}
public MessageBoxEx(Form parent)
{
_msgBox = new MessageBoxExForm(parent);
}
/// <summary>
/// Called by the manager when it is disposed
/// </summary>
internal void Dispose()
{
if(_msgBox != null)
{
_msgBox.Dispose();
}
}
#endregion
}
}

View File

@@ -0,0 +1,52 @@
using System;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// Internal DataStructure used to represent a button
/// </summary>
public class MessageBoxExButton
{
private string _text = null;
/// <summary>
/// Gets or Sets the text of the button
/// </summary>
public string Text
{
get{ return _text; }
set{ _text = value; }
}
private string _value = null;
/// <summary>
/// Gets or Sets the return value when this button is clicked
/// </summary>
public string Value
{
get{ return _value; }
set{_value = value; }
}
private string _helpText = null;
/// <summary>
/// Gets or Sets the tooltip that is displayed for this button
/// </summary>
public string HelpText
{
get{ return _helpText; }
set{ _helpText = value; }
}
private bool _isCancelButton = false;
/// <summary>
/// Gets or Sets wether this button is a cancel button. i.e. the button
/// that will be assumed to have been clicked if the user closes the message box
/// without pressing any button.
/// </summary>
public bool IsCancelButton
{
get{ return _isCancelButton; }
set{ _isCancelButton = value; }
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// Standard MessageBoxEx buttons
/// </summary>
public enum MessageBoxExButtons
{
Ok = 0,
Cancel = 1,
Yes = 2,
No = 4,
Abort = 8,
Retry = 16,
Ignore = 32
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,387 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used forserialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="panelIcon.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="panelIcon.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="panelIcon.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="panelIcon.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="panelIcon.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="panelIcon.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="chbSaveResponse.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="chbSaveResponse.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="chbSaveResponse.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="imageListIcons.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="imageListIcons.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="imageListIcons.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</data>
<data name="imageListIcons.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFpTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0xLjAuNTAw
MC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZT
eXN0ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMA
AADELQAAAk1TRnQBSQFMAgEBBAEAAQUBAAEEAQABIAEAASABAAT/AREBEAj/AUIBTQE2BwABNgMAASgD
AAGAAwABQAMAAQEBAAEQBgABQP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wA8AAEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARAB
QgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARAB
QgEQAUIqAAEQAUIBEAFCMAABEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQjwAARABQgEQAUIe
AAEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARAB
QgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQiYAARABQgEQAUIB
EAFCKgABEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCARAB
QjQAARABQgEQAUIBEAFCGwABQjAAARABQgEQAUIBEAFCARABQgEQAUImAAEQAUIBEAFCKAABEAFCARAB
QgEAAUABAAFAAQABQAEAAUABAAFAAQABQAEAAUABAAFAARABQgEQAUIBEAFCARABQgEQAUIBEAFCNAAB
EAFCARABQhkAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8BGAFjAgABEAFCARAB
QgEQAUIBEAFCIgAB/wF/AgABEAFCARABQiQAARABQgEAAUABAAFAAQABQAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABQAEAAUABAAFAARABQgEQAUIBEAFCARABQgEQAUIsAAH/AX8CAAEQAUIB
EAFCFwABQgHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/ARgBYwIAARAB
QgEQAUIBEAFCIAAB/wF/Af8BfwIAARABQgEQAUIiAAEQAUIBAAFAAQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAFAARABQgEQAUIBEAFCARABQgEQAUIo
AAH/AX8B/wF/AgABEAFCARABQhcAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B
4AF/AeABfwHgAX8CAAEQAUIBEAFCARABQhoAARABQgIAAf8BfwH/AX8B/wF/AgABEAFCARABQiEAAUAB
AAFAAQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAUABAAFAARABQgEQAUIBEAFCARABQiAAARABQgIAAf8BfwH/AX8B/wF/AgABEAFCARAB
QhcAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8BGAFjBAAB
GAFjAeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8CAAEQAUIBEAFCFgAB
EAFCARABQgEQAUIBEAFCAgAB/wF/Af8BfwH/AX8CAAEQAUIBEAFCARABQgEQAUIBEAFCGQABQAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABQAEQAUIBEAFCARABQhoAARABQgEQAUIBEAFCARABQgIAAf8BfwH/AX8B
/wF/AgABEAFCARABQgEQAUIBEAFCARABQhEAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwHgAX8IAAHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B
GAFjAgABEAFCARABQhIAARABQgEQAUIBEAFCBgABGAFjAf8BfwH/AX8B/wF/AgABEAFCARABQgEQAUIB
EAFCARABQgEQAUIBEAFCEwABQAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAFAARABQgEQAUIB
EAFCFAABEAFCARABQgEQAUIGAAEYAWMB/wF/Af8BfwH/AX8CAAEQAUIBEAFCARABQgEQAUIBEAFCARAB
QgEQAUIPAAFCAeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8IAAHgAX8B
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8CAAEQAUIBEAFCEgABEAFCBgABGAFjAf8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/ARgBYwYAARABQgEQAUIBEAFCARABQgEQAUIRAAFAAQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAUABEAFCARABQgEQAUIBEAFCEAABEAFCBgABGAFjAf8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/ARgBYwYAARABQgEQAUIBEAFCARABQgEQAUINAAFCAeABfwHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8BGAFjBAABGAFjAeABfwHgAX8B4AF/AeABfwHgAX8B
4AF/AeABfwHgAX8B4AF/ARgBYwIAARABQgEQAUIUAAEYAWMB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BGAFjBAABEAFCARABQgEQAUIBEAFCDQABQAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAH/AX8BAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8Af8B
fwEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAUABEAFCARABQgEQAUISAAEYAWMB/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BGAFjBAABEAFCARABQgEQAUIBEAFCDQAB
QgHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AgABEAFCARABQhIAARgBYwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BGAFjAgAB
EAFCARABQgEQAUIBEAFCCQABQAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAH/AX8B/wF/Af8BfwEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8Af8BfwH/AX8B/wF/AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABQAEQAUIBEAFCDgABGAFjAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMCAAEQAUIBEAFCARABQgEQAUILAAFCAeABfwHgAX8B
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8CAAHgAX8B4AF/AeABfwHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwHgAX8BGAFjAgABEAFCARABQhAAAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8CAAEQAUIB
EAFCARABQgEQAUIHAAFAAQABfAEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B/wF/Af8BfwEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAH/AX8B/wF/Af8BfwH/AX8B/wF/AQABfAEAAXwBAAF8AQABfAEAAXwB
AAFAARABQgEQAUIBEAFCCgAB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIBEAFCARABQgsAAUIB
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8BGAFjAgABGAFjAeABfwHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwHgAX8B4AF/AgABEAFCARABQhAAAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/ARgBYwEfAQABHwEAARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwIAARABQgEQAUIBEAFCARABQgUAAUABAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B
/wF/Af8BfwEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B/wF/Af8BfwEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAUABEAFCARABQgEQAUIIAAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8CAAEQAUIB
EAFCARABQgEQAUIJAAFCAeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AQABQgMAAUIB
4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwEYAWMCAAEQAUIBEAFCDAABEAFCAf8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQABHwEAAR8BAAEfAQAB/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/AgABEAFCARABQgEQAUIDAAFAAQABfAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B/wF/Af8BfwEAAXwBAAF8Af8BfwH/AX8B/wF/Af8B
fwH/AX8BAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAUABEAFCARABQgQAARABQgH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/AR8BAAEfAQABHwEAAR8BAAEfAQABHwEAAR8BAAEfAQAB
HwEAAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIBEAFCCwABQgHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwHgAX8B4AF/BgAB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwIAARAB
QgEQAUIMAAEQAUIBGAFjAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQAB
HwEAAR8BAAEfAQAB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/ARgBYwIAARAB
QgEQAUIBEAFCAQABQAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQAB
fAEAAXwBAAFAARABQgEQAUICAAEQAUIBGAFjAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwEfAQABHwEAAR8BAAEfAQABHwEAAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/ARgBYwIAARABQgEQAUIBEAFCCQABQgHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8BGAFjBgAB
GAFjAeABfwHgAX8B4AF/AeABfwHgAX8B4AF/ARgBYwIAARABQgEQAUIMAAEQAUIB/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMBHwEAAR8BAAEYAWMB/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIBEAFCAQABQAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAFAARABQgEQAUICAAEQAUIB
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQABHwEAAR8BAAEfAQAB
HwEAAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIBEAFCCwAB
QgHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwEAAUIHAAFCAeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AgAB
EAFCARABQgwAARABQgEYAWMB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwEYAWMCAAEQAUIBEAFCAQABQAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAFAARABQgEQAUIBEAFCARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/AR8BAAEfAQABHwEAAR8BAAEfAQAB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/ARgBYwIAARABQgEQAUILAAFCAeABfwHgAX8B4AF/AeABfwHgAX8B4AF/CgAB
4AF/AeABfwHgAX8B4AF/AeABfwEYAWMCAAEQAUIBEAFCDAABEAFCAf8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQABHwEAAf8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIBAAFAAQABfAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAUABEAFCARABQgEQAUIB/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BHwEAAR8BAAEfAQABHwEAAR8B
AAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/AgABEAFCARABQg0AAUIB
4AF/AeABfwHgAX8B4AF/AeABfwoAAeABfwHgAX8B4AF/AeABfwHgAX8CAAEQAUIBEAFCDgABEAFCAf8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQABHwEAARgB
YwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIB
AAFAAQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAUAB
EAFCARABQgEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
HwEAAR8BAAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/AgABEAFCARABQg0AAUIB4AF/AeABfwHgAX8B4AF/AeABfwoAAeABfwHgAX8B4AF/AeABfwEYAWMC
AAEQAUIBEAFCDgABEAFCAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwIAARABQgEQAUIBAAFAAQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEAAXwBAAF8AQABfAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAUABEAFCAgABEAFCAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/AR8BAAEfAQABHwEAAR8BAAEfAQAB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwIAARABQgEQAUIPAAFCAeABfwHgAX8B4AF/AeABfwoAAeABfwHgAX8B
4AF/AeABfwIAARABQgEQAUIQAAEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/ARgBYwEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/AgABEAFCARABQgEAAUABAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQAB
fAH/AX8B/wF/Af8BfwH/AX8B/wF/AQABfAEAAXwB/wF/Af8BfwH/AX8B/wF/Af8BfwEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABQAEQAUICAAEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BHwEAAR8BAAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/AgABEAFCARABQg8AAUIB4AF/AeABfwHgAX8B4AF/CgAB
4AF/AeABfwHgAX8BGAFjAgABEAFCARABQhAAARABQgH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwEYAWMBHwEAAR8BAAEYAWMB/wF/AR8BAAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8CAAEQAUIFAAFAAQABfAEAAXwBAAF8AQABfAEAAXwBAAF8Af8B
fwH/AX8B/wF/Af8BfwH/AX8BAAF8AQABfAEAAXwBAAF8Af8BfwH/AX8B/wF/Af8BfwH/AX8BAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAFAARABQgEQAUICAAEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/AR8BAAEfAQABHwEAAR8BAAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/AgABEAFCEwABQgHgAX8B4AF/AeABfwEYAWMGAAEYAWMB
4AF/AeABfwHgAX8CAAEQAUIBEAFCEgABEAFCARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/AR8BAAEfAQABHwEAAR8BAAH/AX8BGAFjAR8BAAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/ARgBYwIAARABQgUAAUABAAF8AQABfAEAAXwBAAF8AQABfAH/AX8B/wF/Af8B
fwH/AX8B/wF/AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8Af8BfwH/AX8B/wF/Af8BfwH/AX8BAAF8AQAB
fAEAAXwBAAF8AQABfAEAAUABEAFCBAABEAFCARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/ARgBYwIAARABQhMAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeAB
fwHgAX8B4AF/ARgBYwIAARABQgEQAUIUAAEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwEfAQABHwEAAR8BAAEfAQAB/wF/Af8BfwEfAQABHwEAAR8BAAEfAQAB/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwIAARABQgcAAUABAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB/wF/Af8BfwH/AX8B
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAH/AX8B/wF/Af8BfwEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAUAIAAEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwIAARABQhcAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeABfwHgAX8CAAEQAUIBEAFCFgAB
EAFCARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B
HwEAAR8BAAEfAQABHwEAAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMNAAFAAQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8Af8BfwEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
/wF/AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABQAEQAUIIAAEQAUIBGAFjAf8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/ARgBYwEfAQABHwEAAR8BAAEfAQABGAFjAf8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/ARgBYxsAAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AeAB
fwEYAWMCAAEQAUIBEAFCGAABEAFCAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMBHwEAARgB
YwH/AX8B/wF/AR8BAAEfAQABHwEAAR8BAAEYAWMB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/EQAB
QAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAFAARABQgwAARABQgH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQABHwEAAR8BAAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8Bfx8AAUIB4AF/AeABfwHgAX8B4AF/AeABfwHgAX8B4AF/AgABEAFCARAB
QhwAARABQgH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BGAFjAR8BAAEfAQABHwEAAR8BAAEfAQAB
HwEAARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8TAAFAAQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwB
AAF8AQABfAEAAUAQAAEQAUIB/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEfAQABHwEAAR8B
AAEfAQABHwEAAR8BAAH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/IQABQgHgAX8B4AF/AeAB
fwHgAX8B4AF/AeABfwEYAWMCAAEQAUIBEAFCHgABEAFCAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8XAAFAAQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAFAFAABEAFCAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMB
HwEAAR8BAAEfAQABHwEAARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8lAAFCAeABfwHgAX8B
4AF/AeABfwHgAX8CAAEQAUIBEAFCIgABEAFCARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8BGAFjARABQhkAAUABAAFAAQABfAEAAXwB
AAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAUAB
AAFAGAABEAFCARgBYwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8B
fwH/AX8B/wF/Af8BfwH/AX8BGAFjARABQiUAAUIB4AF/AeABfwHgAX8B4AF/ARgBYwIAARABQiYAARAB
QgEQAUIBGAFjAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/ARgB
YwEQAUIBEAFCHwABQAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAXwBAAF8AQAB
fAEAAXwBAAF8AQABQB4AARABQgEQAUIBGAFjAf8BfwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwH/AX8B
/wF/Af8BfwH/AX8B/wF/ARgBYwEQAUIBEAFCKQABQgHgAX8B4AF/ARgBYzAAARABQgEQAUIBEAFCARgB
YwH/AX8B/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMBEAFCARABQgEQAUIlAAFAAQABQAEAAUABAAF8AQAB
fAEAAXwBAAF8AQABfAEAAXwBAAF8AQABfAEAAUABAAFAAQABQCQAARABQgEQAUIBEAFCARgBYwH/AX8B
/wF/Af8BfwH/AX8B/wF/Af8BfwEYAWMBEAFCARABQgEQAUIvAAFCAQABQgEAAUI2AAEQAUIBEAFCARAB
QgEQAUIBEAFCARABQgEQAUIBEAFCMQABQAEAAUABAAFAAQABQAEAAUABAAFAAQABQAEAAUAwAAEQAUIB
EAFCARABQgEQAUIBEAFCARABQgEQAUIBEAFCGgABQgFNAT4HAAE+AwABKAMAAYADAAFAAwABAQEAAQEG
AAEEFgAD//8A/wADAAH4AgABAwL/AecC/wH4AQcD/wHnAf8B8AIAAQEC/wHHAv8BwAEAA/8BxwH/AcAD
AAL/AYcC/wGAAQABfwL/AYcB/wGAAwAC/wEHAf8B/gIAAR8C/wEHAf8EAAH/Af4BBwH/AfwCAAEPAf8B
/gEHAf8EAAH/AfgBBwH/AfgCAAEHAf8B+AEHAf8DAAEBAf8BwAEAAf8B8AIAAQcB/wHAAQAB/wMAAQEB
/wIAAT8B4AIAAQMB/wIAAT8BgAIAAQMB/gIAAR8B4AIAAQEB/gIAAR8BgAIAAQMB/AIAAQ8BwAIAAQEB
/AIAAQ8BwAIAAQcB+AIAAQcBgAIAAQEB+AIAAQcBwAIAAQcB8AIAAQMBgAMAAfACAAEDAeACAAEPAeAC
AAEBAYADAAHgAgABAQHgAgABDwHAAgABAQQAAcACAAEBAfACAAEfAYAHAAGAAwAB8AIAAR8BgAcAAYAD
AAH4AgABPwwAAfgCAAE/DAAB/AIAAX8MAAH8AgABfwcAAQEEAAH+AgAB/wcAAQEEAAH+AgAB/wMAAQEB
gAIAAQEDAAEBAf8BAAEBAf8DAAEBAYACAAEDAwABAQH/AQABAQH/AYACAAEDAYACAAEHAYACAAEDAf8B
gAEDAf8BgAIAAQcBwAIAAQcBgAIAAQcB/wGAAQMB/wHAAgABDwHgAgABDwHAAgABDwH/AcABBwH/AeAC
AAEfAeACAAEfAeACAAEfAf8BwAEHAf8B8AIAAT8B8AIAAT8B8AIAAT8B/wHgAQ8B/wH4AgABfwH4AgAB
fwH4AgABfwH/AeABHwH/AfwCAAH/Af4BAAEBAf8B/AIAAv8B8AF/Av8BAAEDAv8BAAEDAv8BAAEDAv8B
+AP/AeABHwL/AeABHwL/AeABHwH/FgAL
</value>
</data>
<data name="buttonToolTip.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="buttonToolTip.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>142, 17</value>
</data>
<data name="buttonToolTip.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="rtbMessage.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="rtbMessage.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="rtbMessage.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>(Default)</value>
</data>
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</data>
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>8, 8</value>
</data>
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>80</value>
</data>
<data name="$this.Name">
<value>MessageBoxExForm</value>
</data>
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</data>
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>Private</value>
</data>
</root>

View File

@@ -0,0 +1,20 @@
using System;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// Standard MessageBoxEx icons
/// </summary>
public enum MessageBoxExIcon
{
None,
Asterisk,
Error,
Exclamation,
Hand,
Information,
Question,
Stop,
Warning
}
}

View File

@@ -0,0 +1,218 @@
using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;
using System.Resources;
using System.Reflection;
using System.Text.RegularExpressions;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// Manages a collection of MessageBoxes. Basically manages the
/// saved response handling for messageBoxes.
/// </summary>
public class MessageBoxExManager
{
#region Fields
private static Hashtable _messageBoxes = new Hashtable();
private static Hashtable _savedResponses = new Hashtable();
private static Hashtable _standardButtonsText = new Hashtable();
#endregion
#region Static ctor
static MessageBoxExManager()
{
try
{
Assembly current = typeof(MessageBoxExManager).Assembly;
string[] resources = current.GetManifestResourceNames();
string standardButtonsTextResourceName = "";
Match SPMatch;
foreach (string resource in resources)
{
SPMatch = Regex.Match(resource,@"^(.+StandardButtonsText)\.resources$", RegexOptions.IgnoreCase);
if (SPMatch.Success && SPMatch.Groups.Count > 1)
{
standardButtonsTextResourceName = SPMatch.Groups[1].Value;
break;
}
}
ResourceManager rm = new ResourceManager(standardButtonsTextResourceName, typeof(MessageBoxExManager).Assembly);
_standardButtonsText[MessageBoxExButtons.Ok.ToString()] = rm.GetString("Ok");
_standardButtonsText[MessageBoxExButtons.Cancel.ToString()] = rm.GetString("Cancel");
_standardButtonsText[MessageBoxExButtons.Yes.ToString()] = rm.GetString("Yes");
_standardButtonsText[MessageBoxExButtons.No.ToString()] = rm.GetString("No");
_standardButtonsText[MessageBoxExButtons.Abort.ToString()] = rm.GetString("Abort");
_standardButtonsText[MessageBoxExButtons.Retry.ToString()] = rm.GetString("Retry");
_standardButtonsText[MessageBoxExButtons.Ignore.ToString()] = rm.GetString("Ignore");
}
catch(Exception ex)
{
System.Diagnostics.Debug.Assert(false, "Unable to load resources for MessageBoxEx", ex.ToString());
//Load default resources
_standardButtonsText[MessageBoxExButtons.Ok.ToString()] = "Ok";
_standardButtonsText[MessageBoxExButtons.Cancel.ToString()] = "Cancel";
_standardButtonsText[MessageBoxExButtons.Yes.ToString()] = "Yes";
_standardButtonsText[MessageBoxExButtons.No.ToString()] = "No";
_standardButtonsText[MessageBoxExButtons.Abort.ToString()] = "Abort";
_standardButtonsText[MessageBoxExButtons.Retry.ToString()] = "Retry";
_standardButtonsText[MessageBoxExButtons.Ignore.ToString()] = "Ignore";
}
}
#endregion
#region Methods
/// <summary>
/// Creates a new message box with the specified name. If null is specified
/// in the message name then the message box is not managed by the Manager and
/// will be disposed automatically after a call to Show()
/// </summary>
/// <param name="name">The name of the message box</param>
/// <returns>A new message box</returns>
public static MessageBoxEx CreateMessageBox(Form parentForm, string name)
{
if(name != null && _messageBoxes.ContainsKey(name))
{
string err = string.Format("A MessageBox with the name {0} already exists.",name);
throw new ArgumentException(err,"name");
}
MessageBoxEx msgBox = new MessageBoxEx(parentForm);
msgBox.Name = name;
if(msgBox.Name != null)
{
_messageBoxes[name] = msgBox;
}
return msgBox;
}
/// <summary>
/// Gets the message box with the specified name
/// </summary>
/// <param name="name">The name of the message box to retrieve</param>
/// <returns>The message box with the specified name or null if a message box
/// with that name does not exist</returns>
public static MessageBoxEx GetMessageBox(string name)
{
if(_messageBoxes.Contains(name))
{
return _messageBoxes[name] as MessageBoxEx;
}
else
{
return null;
}
}
/// <summary>
/// Deletes the message box with the specified name
/// </summary>
/// <param name="name">The name of the message box to delete</param>
public static void DeleteMessageBox(string name)
{
if(name == null)
return;
if(_messageBoxes.Contains(name))
{
MessageBoxEx msgBox = _messageBoxes[name] as MessageBoxEx;
msgBox.Dispose();
_messageBoxes.Remove(name);
}
}
public static void WriteSavedResponses(Stream stream)
{
throw new NotImplementedException("This feature has not yet been implemented");
}
public static void ReadSavedResponses(Stream stream)
{
throw new NotImplementedException("This feature has not yet been implemented");
}
/// <summary>
/// Reset the saved response for the message box with the specified name.
/// </summary>
/// <param name="messageBoxName">The name of the message box whose response is to be reset.</param>
public static void ResetSavedResponse(string messageBoxName)
{
if(messageBoxName == null)
return;
if(_savedResponses.ContainsKey(messageBoxName))
{
_savedResponses.Remove(messageBoxName);
}
}
/// <summary>
/// Resets the saved responses for all message boxes that are managed by the manager.
/// </summary>
public static void ResetAllSavedResponses()
{
_savedResponses.Clear();
}
#endregion
#region Internal Methods
/// <summary>
/// Set the saved response for the specified message box
/// </summary>
/// <param name="msgBox">The message box whose response is to be set</param>
/// <param name="response">The response to save for the message box</param>
internal static void SetSavedResponse(MessageBoxEx msgBox, string response)
{
if(msgBox.Name == null)
return;
_savedResponses[msgBox.Name] = response;
}
/// <summary>
/// Gets the saved response for the specified message box
/// </summary>
/// <param name="msgBox">The message box whose saved response is to be retrieved</param>
/// <returns>The saved response if exists, null otherwise</returns>
internal static string GetSavedResponse(MessageBoxEx msgBox)
{
string msgBoxName = msgBox.Name;
if(msgBoxName == null)
{
return null;
}
if(_savedResponses.ContainsKey(msgBoxName))
{
return _savedResponses[msgBox.Name].ToString();
}
else
{
return null;
}
}
/// <summary>
/// Returns the localized string for standard button texts like,
/// "Ok", "Cancel" etc.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
internal static string GetLocalizedString(string key)
{
if(_standardButtonsText.ContainsKey(key))
{
return (string)_standardButtonsText[key];
}
else
{
return null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// Standard MessageBoxEx results
/// </summary>
public struct MessageBoxExResult
{
public const string Ok = "Ok";
public const string Cancel = "Cancel";
public const string Yes = "Yes";
public const string No = "No";
public const string Abort = "Abort";
public const string Retry = "Retry";
public const string Ignore = "Ignore";
public const string Timeout = "Timeout";
}
}

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Ok">
<value>O.K.</value>
</data>
<data name="Cancel">
<value>Löschen</value>
</data>
<data name="Yes">
<value>Ja</value>
</data>
<data name="No">
<value>Nein</value>
</data>
<data name="Abort">
<value>Abbruch</value>
</data>
<data name="Retry">
<value>Wiederholung</value>
</data>
<data name="Ignore">
<value>Ignorieren</value>
</data>
</root>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Ok">
<value>Ok</value>
</data>
<data name="Cancel">
<value>Annuler</value>
</data>
<data name="Yes">
<value>Oui</value>
</data>
<data name="No">
<value>Non</value>
</data>
<data name="Abort">
<value>Arrêt</value>
</data>
<data name="Retry">
<value>Nouvelle</value>
</data>
<data name="Ignore">
<value>Ignorez</value>
</data>
</root>

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="ResMimeType">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="Version">
<value>1.0.0.0</value>
</resheader>
<resheader name="Reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="Writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Ok">
<value>Ok</value>
</data>
<data name="Cancel">
<value>Cancel</value>
</data>
<data name="Yes">
<value>Yes</value>
</data>
<data name="No">
<value>No</value>
</data>
<data name="Abort">
<value>Abort</value>
</data>
<data name="Retry">
<value>Retry</value>
</data>
<data name="Ignore">
<value>Ignore</value>
</data>
</root>

View File

@@ -0,0 +1,29 @@
using System;
namespace CommonLib.Windows.Forms
{
/// <summary>
/// Enumerates the kind of results that can be returned when a
/// message box times out
/// </summary>
public enum TimeoutResult
{
/// <summary>
/// On timeout the value associated with the default button is set as the result.
/// This is the default action on timeout.
/// </summary>
Default,
/// <summary>
/// On timeout the value associated with the cancel button is set as the result. If
/// the messagebox does not have a cancel button then the value associated with
/// the default button is set as the result.
/// </summary>
Cancel,
/// <summary>
/// On timeout MessageBoxExResult.Timeout is set as the result.
/// </summary>
Timeout
}
}

View File

@@ -0,0 +1,184 @@
///======================================================================================
/// File: frmChildForm.cs
/// Created: 06/06/12
///======================================================================================
/// <summary>
/// A base child form with unique characteristics
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace CommonLib.Windows.Forms
{
///======================================================================================
/// ChildForm
///======================================================================================
/// <summary>
/// This class is a base class for any child form that has a calling parent form. Any
/// class inheriting this class will be able to display the child form at the center
/// of the parent form by notifying the child form of its parent form
/// </summary>
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ----------- ----------- ----- ------------------------------------------
/// 06/06/12 D.Le
///======================================================================================
public partial class ChildForm : Form
{
//property
public Form parentForm
{
get;
set;
}
public ChildForm()
{
InitializeComponent();
parentForm = null;
}
///==========================================================================
/// ChildForm.OnLoad
///==========================================================================
/// <summary>
/// Form's OnLoad Event Handler. If the parent form is passed in then display
/// this form at the center of the parent form
/// </summary>
/// <param name="e"></param>
/// <return>void</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
protected override void OnLoad(EventArgs e)
{
if (parentForm != null)
CenterForm(parentForm);
base.OnLoad(e);
}
///==========================================================================
/// ChildForm.OnLoad
///==========================================================================
/// <summary>
/// Centers the form relative to the parent form. Also moves the form into
/// visible area of the screen if it's determined that an area of the form
/// is position outside of the screen's visible area
/// </summary>
/// <param name="parentForm">The parent form that calls this form</param>
/// <return>void</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
private void CenterForm(Form parentForm)
{
List<Screen> allScreens = new List<Screen>();
int parentCenterX, parentCenterY, childTopX, childTopY,
childVisibleTopX, childVisibleBottomX,
screenVisibleBottomX, screenVisibleBottomY, rectWidth, trueChildWidth, screensCount=0;
// create the smallest rectangle
Rectangle rect = new Rectangle(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);
// determines the coordinate of the center of the parent form
// that will be used as the center of the pop-up box
parentCenterX = parentForm.Left + parentForm.Width / 2;
parentCenterY = parentForm.Top + parentForm.Height / 2;
childTopX = parentCenterX - this.Width / 2;
childTopY = parentCenterY - this.Height / 2;
// if the x coordinate is off the screen to the left, we move it to the visible area of screen
if (childTopX < 0)
{
trueChildWidth = childTopX + this.Width;
childTopX = 0;
}
else
trueChildWidth = this.Width;
// if the y coordinate is off the screen up above, we move it to the visible area of screen
if (childTopY < 0)
childTopY = 0;
foreach (Screen screen in Screen.AllScreens)
{
if (screen.Primary)
allScreens.Insert(0, screen);
else
allScreens.Add(screen);
}
foreach (Screen screen in allScreens)
{
screensCount++;
if (rect.Width < 0)
rectWidth = 0;
else
rectWidth = rect.Width;
rect = Rectangle.Union(rect, screen.Bounds); // join screens
// if we're on the last screen
if ( Screen.AllScreens.Length == screensCount )
{
// if the x coordinate is off the screen to the right, we move it to the visible area of screen
if ((childTopX + this.Width) > rect.Width)
{
trueChildWidth = rect.Width - childTopX;
}
}
screenVisibleBottomX = screen.WorkingArea.X + screen.WorkingArea.Width;
screenVisibleBottomY = screen.WorkingArea.Y + screen.WorkingArea.Height;
if (childTopX <= rectWidth)
{
childVisibleTopX = rectWidth + 1;
}
else
childVisibleTopX = childTopX;
if ((childTopX + trueChildWidth) > (rectWidth + screen.Bounds.Width))
childVisibleBottomX = rectWidth + screen.Bounds.Width;
else
childVisibleBottomX = childTopX + trueChildWidth;
// determine if the visible width of the form is 50% or greater, then we choose
// to display this form on this screen
if ( Convert.ToInt32(Math.Ceiling(((double)(childVisibleBottomX - childVisibleTopX) / (double)trueChildWidth)*100.0)) >= 50 )
{
if (childTopX < screen.WorkingArea.X)
childTopX = screen.WorkingArea.X;
else if ((childTopX + this.Width) > screenVisibleBottomX)
childTopX -= (childTopX + this.Width) - screenVisibleBottomX;
if (childTopY < screen.WorkingArea.Y)
childTopY = screen.WorkingArea.Y;
else if ((childTopY + this.Height) > screenVisibleBottomY)
childTopY -= (childTopY + this.Height) - screenVisibleBottomY;
break;
}
}
this.Location = new Point(childTopX, childTopY);
}
}
}

View File

@@ -0,0 +1,38 @@
namespace CommonLib.Windows.Forms
{
partial class ChildForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Forms";
}
#endregion
}
}

View File

@@ -0,0 +1,612 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.NetworkInformation;
using System.Management;
using System.Runtime.InteropServices;
using System.IO;
using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.Security.Principal;
using System.Security.AccessControl;
using CommonLib.IO;
using CommonLib.Misc;
using CommonLib.Diagnostics;
namespace CommonLib.Windows.Misc
{
public class NetworkManagement
{
//////==========================================================================
/// NetworkSharing.GetNetworkAdapterAndConfigurationBasedOnPciLocation
///==========================================================================
/// <summary>
/// Given PCI Location (bus,device,function), obtain references to objects of
/// type Win32_NetworkAdapter and Win32_NetworkAdapterConfiguration.
/// These two object provides us with a wide array of information about the
/// network adapter
/// </summary>
/// <param name="networkAdapter">
/// This object must be of type Win32_NetworkAdapter
/// </param>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="expectedPciLocation">
/// Must be in this format: #,#,# (bus,device,function)
/// i.e.: 61,7,2
/// Every PCI network adapter has a unique location.
/// </param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool GetNetworkAdapterAndConfigurationBasedOnPciLocation(ref ManagementObject networkAdapter, ref ManagementObject networkAdapterConfiguration, string expectedPciLocation, ref string errMsg)
{
bool successful = true;
errMsg = "";
networkAdapter = null;
networkAdapterConfiguration = null;
ManagementObjectSearcher mos = null;
Match regExMatch;
string valueName = "LocationInformation";
string registryValueNameValue = "";
string actualPciLocationInfo = "";
try
{
if (expectedPciLocation.Length == 0)
{
throw new Exception("PCI Location cannot be empty. Provide PCI Location in the form: #,#,# representing bus,device,function");
}
else
{
expectedPciLocation = Regex.Replace(expectedPciLocation, @"\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*", "$1,$2,$3", RegexOptions.IgnoreCase);
}
mos = new ManagementObjectSearcher(@"SELECT *
FROM Win32_NetworkAdapter
WHERE Manufacturer != 'Microsoft'
AND NOT PNPDeviceID LIKE 'ROOT\\%'");
if (mos == null)
{
throw new Exception("No network adapter found in the system");
}
foreach (ManagementObject adapter in mos.Get())
{
// print out all the properties name/value for each adapter
//foreach (PropertyData pd in adapter.Properties)
// Console.WriteLine(pd.Name + ": " + (pd.Value ?? "N/A"));
//Console.WriteLine("Index: {0}, Name: {1}", adapter["DeviceID"],adapter["Name"]);
string pnpDeviceIdRegistryPath = @"SYSTEM\CurrentControlSet\Enum\" + adapter["PNPDeviceID"];
RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey rkSubKey = hklm.OpenSubKey(pnpDeviceIdRegistryPath, false);
List<string> list = new List<string>(rkSubKey.GetValueNames());
// if there's a name "LocationInformation" found in the registry key
if (list.FindIndex(x => x.Equals(valueName, StringComparison.OrdinalIgnoreCase)) != -1)
{
// get the value associated with LocationInformation
registryValueNameValue = rkSubKey.GetValue(valueName).ToString();
regExMatch = Regex.Match(registryValueNameValue, @".+\((\d+,\d+,\d+)\)$", RegexOptions.IgnoreCase);
if (regExMatch.Success)
{
// get actual pci location in this format #,#,# which corresponds to bus,device,function
actualPciLocationInfo = regExMatch.Groups[1].Value;
}
}
if (expectedPciLocation == actualPciLocationInfo)
{
networkAdapter = adapter;
foreach (ManagementObject configuration in
adapter.GetRelated("Win32_NetworkAdapterConfiguration"))
{
// print out all the properties name/value for each configuration
//foreach (PropertyData pd in configuration.Properties)
// Console.WriteLine(pd.Name + ": " + (pd.Value ?? "N/A"));
networkAdapterConfiguration = configuration;
}
break;
}
}
if (networkAdapterConfiguration == null)
{
throw new Exception("No network adapter found at PCI Location: " + expectedPciLocation);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
//////==========================================================================
/// NetworkSharing.SetNetworkAdapterForDhcp
///==========================================================================
/// <summary>
/// Set network adapter to use DHCP. This is the same thing as setting the adapter
/// to obtain IP and DNS automatically
/// </summary>
/// <param name="networkAdapter">
/// This object must be of type Win32_NetworkAdapter
/// </param>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool SetNetworkAdapterForDhcp(ManagementObject networkAdapter, ManagementObject networkAdapterConfiguration, ref string errMsg)
{
bool successful = true;
errMsg = "";
try
{
if (networkAdapter == null)
{
throw new Exception("Object networkAdapter cannot be null");
}
else if (networkAdapterConfiguration == null)
{
throw new Exception("Object adapterNetworkConfiguration cannot be null");
}
ManagementBaseObject setDhcp;
setDhcp = networkAdapterConfiguration.InvokeMethod("EnableDHCP", null, null);
uint returnedVal = UInt32.Parse(setDhcp["returnValue"].ToString());
// failed because the adapter is disconnected
if (returnedVal == 84)
{
string adapterGuid = @"SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\" + networkAdapter["GUID"];
successful = WindowsRegistry.AddOrModifyRegistryKeySingleValue(adapterGuid, RegistryHive.LocalMachine, "EnableDHCP", RegistryValueKind.String, "1", ref errMsg);
if (!successful)
throw new Exception(errMsg);
// set dns server to be obtained automatically
successful = WindowsRegistry.AddOrModifyRegistryKeySingleValue(adapterGuid, RegistryHive.LocalMachine, "NameServer", RegistryValueKind.String, "", ref errMsg);
if (!successful)
throw new Exception(errMsg);
successful = WindowsRegistry.DeleteRegistryValueName(adapterGuid, RegistryHive.LocalMachine, "DisableDhcpOnConnect", ref errMsg);
if (!successful)
throw new Exception(errMsg);
successful = WindowsRegistry.DeleteRegistryValueName(adapterGuid, RegistryHive.LocalMachine, "DefaultGateway", ref errMsg);
if (!successful)
throw new Exception(errMsg);
successful = WindowsRegistry.DeleteRegistryValueName(adapterGuid, RegistryHive.LocalMachine, "DefaultGatewayMetric", ref errMsg);
if (!successful)
throw new Exception(errMsg);
successful = WindowsRegistry.DeleteRegistryValueName(adapterGuid, RegistryHive.LocalMachine, "IPAddress", ref errMsg);
if (!successful)
throw new Exception(errMsg);
successful = WindowsRegistry.DeleteRegistryValueName(adapterGuid, RegistryHive.LocalMachine, "SubnetMask", ref errMsg);
if (!successful)
throw new Exception(errMsg);
}
else if (returnedVal != 0)
{
throw new Exception("Unable to enable DHCP for this network adapter. Error code: " + setDhcp["returnValue"]);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
//////==========================================================================
/// NetworkSharing.SetNetworkAdapterIpAddress
///==========================================================================
/// <summary>
/// Set network adapter's IP address and subnet mask
/// </summary>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="ipAddress">i.e 192.168.0.1</param>
/// <param name="subnetMask">i.e 255.255.255.0</param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool SetNetworkAdapterIpAddress(ManagementObject networkAdapterConfiguration, string ipAddress, string subnetMask, ref string errMsg)
{
bool successful = true;
errMsg = "";
try
{
if (!StringManip.IsValidIPv4(ipAddress))
{
throw new Exception(ipAddress + " is an invalid IPv4 Address");
}
else if (!StringManip.IsValidIPv4(subnetMask))
{
throw new Exception(subnetMask + " is an invalid IPv4 Address");
}
ManagementBaseObject setIP;
ManagementBaseObject newIP =
networkAdapterConfiguration.GetMethodParameters("EnableStatic");
newIP["IPAddress"] = new string[] { ipAddress };
newIP["SubnetMask"] = new string[] { subnetMask };
setIP = networkAdapterConfiguration.InvokeMethod("EnableStatic", newIP, null);
uint returnedVal = UInt32.Parse(setIP["returnValue"].ToString());
if (returnedVal != 0)
{
throw new Exception("Unable to change IP address/subnet mask for this network adapter. Error code: " + setIP["returnValue"]);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
//////==========================================================================
/// NetworkSharing.SetNetworkAdapterDefaultGateway
///==========================================================================
/// <summary>
/// Set default gateway for network adapter
/// </summary>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="defaultGateway">
/// IP address for the gateway
/// </param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool SetNetworkAdapterDefaultGateway(ManagementObject networkAdapterConfiguration, string defaultGateway, ref string errMsg)
{
bool successful = true;
errMsg = "";
try
{
if (!StringManip.IsValidIPv4(defaultGateway))
{
throw new Exception(defaultGateway + " is an invalid IPv4 IP Address");
}
ManagementBaseObject setGateway;
ManagementBaseObject newGateway = networkAdapterConfiguration.GetMethodParameters("SetGateways");
newGateway["DefaultIPGateway"] = new string[] { defaultGateway };
newGateway["GatewayCostMetric"] = new int[] { 1 };
setGateway = networkAdapterConfiguration.InvokeMethod("SetGateways", newGateway, null);
uint returnedVal = UInt32.Parse(setGateway["returnValue"].ToString());
if (returnedVal != 0)
{
throw new Exception("Unable to change default gateway for this network adapter. Error code: " + setGateway["returnValue"]);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
//////==========================================================================
/// NetworkSharing.SetNetworkAdapterDnsServers
///==========================================================================
/// <summary>
/// Set DNS servers for the network adapter
/// </summary>
/// <param name="networkAdapter">
/// This object must be of type Win32_NetworkAdapter
/// </param>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="dnsServers">
/// Must provide at least one IP address for DNS server, maximum is 2 IP addresses
/// </param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool SetNetworkAdapterDnsServers(ManagementObject networkAdapter, ManagementObject networkAdapterConfiguration, List<string> dnsServerList, ref string errMsg)
{
bool successful = true;
errMsg = "";
string nameServer = "";
try
{
if (networkAdapter == null)
{
throw new Exception("Object networkAdapter cannot be null");
}
else if (networkAdapterConfiguration == null)
{
throw new Exception("Object adapterNetworkConfiguration cannot be null");
}
else if (dnsServerList.Count == 0 || dnsServerList == null)
{
throw new Exception("DNS Server information not provided");
}
for (int i = 0; i < dnsServerList.Count; i++)
{
if (!StringManip.IsValidIPv4(dnsServerList[i].Trim()))
{
throw new Exception(dnsServerList[i].Trim() + " is an invalid IPv4 IP Address");
}
if (nameServer.Length == 0)
nameServer = dnsServerList[i].Trim();
else
nameServer += "," + dnsServerList[i].Trim(); ;
}
string[] dnsServers = dnsServerList.ToArray();
ManagementBaseObject newDNS =
networkAdapterConfiguration.GetMethodParameters("SetDNSServerSearchOrder");
newDNS["DNSServerSearchOrder"] = dnsServers;
ManagementBaseObject setDNS =
networkAdapterConfiguration.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
uint returnedVal = UInt32.Parse(setDNS["returnValue"].ToString());
// failed because the adapter is disconnected
if (returnedVal == 84)
{
string adapterGuid = @"SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\" + networkAdapter["GUID"];
successful = WindowsRegistry.AddOrModifyRegistryKeySingleValue(adapterGuid, RegistryHive.LocalMachine, "NameServer", RegistryValueKind.String, nameServer, ref errMsg);
if (!successful)
throw new Exception(errMsg);
}
else if (returnedVal != 0)
{
throw new Exception("Unable to change default gateway for this network adapter. Error code: " + setDNS["returnValue"]);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
//////==========================================================================
/// NetworkSharing.ChangeNetworkAdapterName
///==========================================================================
/// <summary>
/// Change the name of the network adapter
/// </summary>
/// <param name="networkAdapter">
/// This object must be of type Win32_NetworkAdapter
/// </param>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="adapterName">
/// Name to give the network adapter
/// </param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool ChangeNetworkAdapterName(ManagementObject networkAdapter, ManagementObject networkAdapterConfiguration, string adapterName, ref string errMsg)
{
bool successful = true;
errMsg = "";
string uniqueID = "";
try
{
if (networkAdapter == null)
{
throw new Exception("Object networkAdapter cannot be null");
}
else if (networkAdapterConfiguration == null)
{
throw new Exception("Object adapterNetworkConfiguration cannot be null");
}
else if (adapterName.Length == 0)
{
throw new Exception("adapterName cannot be empty");
}
string adapterGuid = @"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\" + networkAdapter["GUID"] + @"\Connection";
uniqueID = Guid.NewGuid().ToString();
successful = WindowsRegistry.AddOrModifyRegistryKeySingleValue(adapterGuid, RegistryHive.LocalMachine, "Name", RegistryValueKind.String, uniqueID, ref errMsg);
if (!successful)
throw new Exception(errMsg);
ProcessStarter proc = new ProcessStarter();
proc.fileName = @"C:\Windows\System32\netsh.exe";
proc.procArguments = "interface set interface name=\"" + uniqueID + "\" newname=\"" + adapterName + "\"";
proc.Run();
if (proc.procExitCode != 0)
{
throw new Exception("Process netsh.exe returned the following error\n" + proc.outputMsg);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
//////==========================================================================
/// NetworkSharing.SetNetworkAdapterLinkSpeed
///==========================================================================
/// <summary>
/// Set network adapter to use DHCP. This is the same thing as setting the adapter
/// to obtain IP and DNS automatically
/// </summary>
/// <param name="networkAdapter">
/// This object must be of type Win32_NetworkAdapter
/// </param>
/// <param name="networkAdapterConfiguration">
/// This object must be of type Win32_NetworkAdapterConfiguration
/// </param>
/// <param name="linkSpeedValue">
/// Value of the link speed
/// </param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool SetNetworkAdapterLinkSpeed(ManagementObject networkAdapter, ManagementObject networkAdapterConfiguration, string linkSpeedValue, ref string errMsg)
{
bool successful = false;
errMsg = "";
try
{
uint linkSpeed = 0;
if (networkAdapter == null)
{
throw new Exception("Object networkAdapter cannot be null");
}
else if (networkAdapterConfiguration == null)
{
throw new Exception("Object adapterNetworkConfiguration cannot be null");
}
else if (linkSpeedValue.Length == 0)
{
throw new Exception("linkSpeedValue cannot be empty");
}
else if (!UInt32.TryParse(linkSpeedValue, out linkSpeed))
{
throw new Exception("linkSpeedValue must be a number");
}
var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey regSubKey = null;
string registryPath = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}";
regSubKey = hklm.OpenSubKey(registryPath, false);
// get a list of folder names under the registry path above
List<string> keyNameList = new List<string>(regSubKey.GetSubKeyNames());
regSubKey.Close();
// loop through each key name to find the entry for the adapter we are interested in
foreach (string keyName in keyNameList)
{
string vendorRegistryPath = registryPath + @"\" + keyName;
string adapterGuid = WindowsRegistry.GetRegistryValueInString(vendorRegistryPath, RegistryHive.LocalMachine, "NetCfgInstanceId");
// if this is the adapter we are interested in
if (String.Equals(adapterGuid, networkAdapter["GUID"].ToString(), StringComparison.OrdinalIgnoreCase))
{
successful = WindowsRegistry.AddOrModifyRegistryKeySingleValue(vendorRegistryPath, RegistryHive.LocalMachine, "*SpeedDuplex", RegistryValueKind.String, linkSpeedValue, ref errMsg);
if (!successful)
throw new Exception(errMsg);
break;
}
}
if (!successful && errMsg.Length == 0)
throw new Exception("Unable to find a registry entry for this network adapter under " + registryPath);
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
return successful;
}
}
}

View File

@@ -0,0 +1,363 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.NetworkInformation;
using System.Management;
using System.Runtime.InteropServices;
using System.IO;
using Microsoft.Win32;
using System.Text.RegularExpressions;
using System.Security.Principal;
using System.Security.AccessControl;
using CommonLib.IO;
namespace CommonLib.Windows.Misc
{
public class NetworkSharing
{
public static Dictionary<string, WellKnownSidType> userDefinedAccountNameToWellKnowSid = new Dictionary<string, WellKnownSidType>(StringComparer.OrdinalIgnoreCase) {
{ "Everyone" , WellKnownSidType.WorldSid },
{ "Authenticated Users" , WellKnownSidType.AuthenticatedUserSid }
};
//////==========================================================================
/// NetworkSharing.EnableNetworkFolderSharing
///==========================================================================
/// <summary>
/// Enable network sharing of a local folder
/// </summary>
/// <param name="folderPath">Local path of folder to be shared</param>
/// <param name="shareName">name of the network share</param>
/// <param name="description">Description of the share</param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool EnableNetworkFolderSharing(string folderPath, string shareName, string description, ref string errMsg)
{
bool successful = true;
errMsg = "";
if (!Regex.IsMatch(folderPath, @"[a-zA-Z]:.*", RegexOptions.IgnoreCase))
{
errMsg = "Unable to share path " + folderPath + ". Path is invalid";
successful = false;
}
if (successful)
{
// if the path contains at least one folder in it
if (Regex.IsMatch(folderPath, @"[a-zA-Z]:\\[^\\]+", RegexOptions.IgnoreCase))
folderPath = PathManip.RemoveTrailingSlashInPath(folderPath);
else
folderPath = PathManip.AddTrailingSlashToPath(folderPath);
if (!Directory.Exists(folderPath))
{
errMsg = folderPath + "\" does not exist";
successful = false;
}
}
if (successful)
{
try
{
// Create a ManagementClass object
ManagementClass managementClass = new ManagementClass("Win32_Share");
// Create ManagementBaseObjects for in and out parameters
ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
// Set the input parameters
inParams["Description"] = description;
inParams["Name"] = shareName;
inParams["Path"] = folderPath;
inParams["Type"] = 0x0; // Disk Drive
//Another Type:
// DISK_DRIVE = 0x0
// PRINT_QUEUE = 0x1
// DEVICE = 0x2
// IPC = 0x3
// DISK_DRIVE_ADMIN = 0x80000000
// PRINT_QUEUE_ADMIN = 0x80000001
// DEVICE_ADMIN = 0x80000002
// IPC_ADMIN = 0x8000003
inParams["MaximumAllowed"] = null;
inParams["Password"] = null;
inParams["Access"] = null; // Make Everyone has full control access.
//inParams["MaximumAllowed"] = int maxConnectionsNum;
// Invoke the method on the ManagementClass object
outParams = managementClass.InvokeMethod("Create", inParams, null);
// Check to see if the method invocation was successful
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0 && (uint)(outParams.Properties["ReturnValue"].Value) != 22)
{
errMsg = "Error encountered when calling managementClass.InvokeMethod(\"Create\"). Error code: " + outParams.Properties["ReturnValue"].Value.ToString();
successful = false;
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
}
return successful;
}
//////==========================================================================
/// NetworkSharing.addAccountToNetworkShare
///==========================================================================
/// <summary>
/// To add windows account to the permission list of the network
/// share
/// </summary>
/// <param name="folderPath">Local path of folder to be shared</param>
/// <param name="shareName">name of the network share</param>
/// <param name="account">user account. Should be in in the form:
/// DOMAIN\AccountName
/// </param>
/// <param name="description">Description of the share</param>
/// <param name="errMsg">error message returned if error encountered</param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool addAccountToNetworkShare(string folderPath, string shareName, string account, string description, ref string errMsg)
{
bool successful = true;
Match regExMatch;
string domain = "", accountName = "";
if (!Regex.IsMatch(folderPath, @"[a-zA-Z]:.*", RegexOptions.IgnoreCase))
{
errMsg = "Unable to modify user permission for " + folderPath + ". Path is invalid";
successful = false;
}
if (successful)
{
// if the path contains at least one folder in it
if (Regex.IsMatch(folderPath, @"[a-zA-Z]:\\[^\\]+", RegexOptions.IgnoreCase))
folderPath = PathManip.RemoveTrailingSlashInPath(folderPath);
else
folderPath = PathManip.AddTrailingSlashToPath(folderPath);
if (!Directory.Exists(folderPath))
{
errMsg = folderPath + "\" does not exist";
successful = false;
}
}
if (successful)
{
regExMatch = Regex.Match(account, @"(\\\\)?([^\\]+)\\([^\\]+)", RegexOptions.IgnoreCase);
if (regExMatch.Success)
{
domain = regExMatch.Groups[2].Value;
accountName = regExMatch.Groups[3].Value;
}
else if (!isValidWellKnownSid(account))
{
errMsg = "Account \"" + account + "\" is invalid";
successful = false;
}
}
if (successful)
{
try
{
// Create a ManagementClass object
ManagementClass managementClass = new ManagementClass("Win32_Share");
// Create ManagementBaseObjects for in and out parameters
ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
// Set the input parameters
inParams["Description"] = description;
inParams["Name"] = shareName;
inParams["Path"] = folderPath;
inParams["Type"] = 0x0; // Disk Drive
//Another Type:
// DISK_DRIVE = 0x0
// PRINT_QUEUE = 0x1
// DEVICE = 0x2
// IPC = 0x3
// DISK_DRIVE_ADMIN = 0x80000000
// PRINT_QUEUE_ADMIN = 0x80000001
// DEVICE_ADMIN = 0x80000002
// IPC_ADMIN = 0x8000003
inParams["MaximumAllowed"] = null;
inParams["Password"] = null;
inParams["Access"] = null; // Make Everyone has full control access.
//inParams["MaximumAllowed"] = int maxConnectionsNum;
// Invoke the method on the ManagementClass object
outParams = managementClass.InvokeMethod("Create", inParams, null);
// Check to see if the method invocation was successful
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0 && (uint)(outParams.Properties["ReturnValue"].Value) != 22)
{
errMsg = "Error encountered when calling managementClass.InvokeMethod(\"Create\"). Error code: " + outParams.Properties["ReturnValue"].Value.ToString();
successful = false;
}
if (successful)
{
SecurityIdentifier userSID = null;
if (isValidWellKnownSid(account))
{
// get built-in security principals ( Everyone, Authenticated Users, Guests, Administrators, etc)
userSID = new SecurityIdentifier(GetWellKnownSid(account), null);
}
else
{
//user selection
NTAccount ntAccount = new NTAccount(domain, accountName);
//SID
userSID = (SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier));
}
byte[] utenteSIDArray = new byte[userSID.BinaryLength];
userSID.GetBinaryForm(utenteSIDArray, 0);
//Trustee
ManagementObject userTrustee = new ManagementClass(new ManagementPath("Win32_Trustee"), null);
if (domain.Length > 0)
{
userTrustee["Domain"] = domain;
userTrustee["Name"] = accountName;
}
userTrustee["SID"] = utenteSIDArray;
//ACE
ManagementObject userACE = new ManagementClass(new ManagementPath("Win32_Ace"), null);
userACE["AccessMask"] = 2032127; //Full access
userACE["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
userACE["AceType"] = AceType.AccessAllowed;
userACE["Trustee"] = userTrustee;
string rootPath = Regex.Replace(managementClass.Path.ToString(), @"([^:]+:).+", "${1}", RegexOptions.IgnoreCase);
//After we have the new Win_32Ace, now we need to get the existing Ace instances (DACL).
//Create an instance of Win32_LogicalSecuritySetting, set the path to the server and the share.
ManagementObject Win32LogicalSecuritySetting = new ManagementObject(rootPath + "Win32_LogicalShareSecuritySetting.Name='" + shareName + "'");
//Call the GetSecurityDescriptor method. This method returns one out parameter.
ManagementBaseObject Return = Win32LogicalSecuritySetting.InvokeMethod("GetSecurityDescriptor", null, null);
//The return value of that call above has two properties, ReturnValue, which you can use
//to read the status of the call (failed, success, etc.), and Descriptor, which is an instance
//of Win32_SecurityDescriptor.
Int32 returnValue = Convert.ToInt32(Return.Properties["ReturnValue"].Value);
if (returnValue != 0)
throw new Exception(String.Format("Error when calling GetSecurityDescriptor. Error code: {0}.", returnValue));
//Retrieve the array of DACL from the Security Descriptor.
ManagementBaseObject securityDescriptor = Return.Properties["Descriptor"].Value as ManagementBaseObject;
ManagementBaseObject[] DACL = securityDescriptor["DACL"] as ManagementBaseObject[];
if (DACL == null)
DACL = new ManagementBaseObject[] { userACE };
else
{
Array.Resize(ref DACL, DACL.Length + 1);
DACL[DACL.Length - 1] = userACE;
}
//Reassign the new DACL array with the new user Ace back to the Win32_SecurityDescriptor instance, and call the
//SetSecurityDescriptor method.
securityDescriptor["DACL"] = DACL;
ManagementObject share = new ManagementObject(managementClass.Path + ".Name='" + shareName + "'");
returnValue = Convert.ToInt32(share.InvokeMethod("SetShareInfo", new object[] { Int32.MaxValue, description, securityDescriptor }));
if (returnValue != 0)
throw new Exception(String.Format("Error when calling GetSecurityDescriptor. Error code: {0}.", returnValue));
}
}
catch (Exception ex)
{
errMsg = ex.Message;
successful = false;
}
}
return successful;
}
//////==========================================================================
/// NetworkSharing.isValidWellKnownSid
///==========================================================================
/// <summary>
/// Verify if the windows account name user provided is valid
/// </summary>
/// <param name="userDefinedSidAccountName">Windows account name
/// could be Users, Groups or Built-In Security Principals (i.e.:
/// Everyone, Authenticated Users, Guests, etc)
/// </param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static bool isValidWellKnownSid(string userDefinedSidAccountName)
{
bool isValid = true;
if (!userDefinedAccountNameToWellKnowSid.ContainsKey(userDefinedSidAccountName))
isValid = false;
return isValid;
}
//////==========================================================================
/// NetworkSharing.GetWellKnownSid
///==========================================================================
/// <summary>
/// Return the actual Well Known Sid type that matches the windows account
/// name provided by user
/// </summary>
/// <param name="userDefinedSidAccountName">Windows account name
/// could be Users, Groups or Built-In Security Principals (i.e.:
/// Everyone, Authenticated Users, Guests, etc)
/// </param>
/// <return>true/false</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- -----------------------------
/// 12/07/16 D.Le
///==========================================================================
public static WellKnownSidType GetWellKnownSid(string userDefinedSidAccountName)
{
if (isValidWellKnownSid(userDefinedSidAccountName))
return userDefinedAccountNameToWellKnowSid[userDefinedSidAccountName];
else
throw new Exception(userDefinedSidAccountName + " is invalid.");
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CommonLib.Windows.Misc
{
public class WindowShortcut
{
private static Type m_type = Type.GetTypeFromProgID("WScript.Shell");
private static object m_shell = Activator.CreateInstance(m_type);
[ComImport, TypeLibType((short)0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")]
private interface IWshShortcut
{
[DispId(0)]
string FullName { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0)] get; }
[DispId(0x3e8)]
string Arguments { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] set; }
[DispId(0x3e9)]
string Description { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] set; }
[DispId(0x3ea)]
string Hotkey { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] set; }
[DispId(0x3eb)]
string IconLocation { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] set; }
[DispId(0x3ec)]
string RelativePath { [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ec)] set; }
[DispId(0x3ed)]
string TargetPath { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] set; }
[DispId(0x3ee)]
int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; }
[DispId(0x3ef)]
string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] set; }
[TypeLibFunc((short)0x40), DispId(0x7d0)]
void Load([In, MarshalAs(UnmanagedType.BStr)] string PathLink);
[DispId(0x7d1)]
void Save();
}
///==========================================================================
/// Create
///==========================================================================
/// <summary>
/// Create window short cut
/// </summary>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath)
{
IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { fileName });
shortcut.Description = description;
shortcut.Hotkey = hotkey;
shortcut.TargetPath = targetPath;
shortcut.WorkingDirectory = workingDirectory;
shortcut.Arguments = arguments;
if (!string.IsNullOrEmpty(iconPath))
shortcut.IconLocation = iconPath;
shortcut.Save();
}
}
}

View File

@@ -0,0 +1,407 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.AccessControl;
using System.Management;
using System.Security.Principal;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using System.Drawing;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
namespace CommonLib.Windows.Misc
{
public class WindowsAdministration
{
///==========================================================================
/// GetWindowLoginID
///==========================================================================
/// <summary>
/// To get windows login ID, usually it's a simple API call. The problem
/// is when trying to get the windows login ID from a application that is
/// run as an Administrator. In this case, the simple API call will return
/// the Administrator user's ID. This function gets the actual Windows Logon
/// ID regardless what the application is run as.
/// </summary>
/// <param>none</param>
/// <return>string</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetWindowLoginID()
{
string login = "";
string[] properties = { "*" };
SelectQuery s = new SelectQuery("Win32_Process", "Name = 'explorer.exe' ", properties);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(s);
foreach (ManagementObject o in searcher.Get())
{
string[] ownerInfo = { "", "" };
o.InvokeMethod("GetOwner", ownerInfo);
login = ownerInfo[1] + "\\" + ownerInfo[0];
}
return login;
}
///==========================================================================
/// GetDomainName
///==========================================================================
/// <summary>
/// Get the domain name in which the user is logged into. If the computer is
/// not a member of a domain, then the domain name will be the name of the
/// local computer
/// </summary>
/// <param>none</param>
/// <return>string</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetDomainName()
{
string fullLoginID = GetWindowLoginID();
return Regex.Replace(fullLoginID, @"^([^\\]+)\\.+", "$1");
}
///==========================================================================
/// GetUserName
///==========================================================================
/// <summary>
/// Get the user name in which the user is logged into.
/// </summary>
/// <param>none</param>
/// <return>string</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static string GetUserName()
{
string fullLoginID = GetWindowLoginID();
return Regex.Replace(fullLoginID, @"^[^\\]+\\(.+)", "$1");
}
///==========================================================================
/// IsAccountAnAdminAccount
///==========================================================================
/// <summary>
/// Get the domain name in which the user is logged into. If the computer is
/// not a member of a domain, then the domain name will be the name of the
/// local computer
/// </summary>
/// <param name="fullAccountName">Format: [domain]\username, i.e. US\1117637</param>
/// <return>string</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool IsAccountAnAdminAccount(string fullAccountName)
{
bool accountIsAnAdmin = false;
List<string> adminAccounts = GetListOfMemberAccountsFromLocalGroups("Administrators");
foreach (string account in adminAccounts)
{
string tempAccount = Regex.Replace(account, @"/", "\\");
if (Regex.IsMatch(tempAccount, Regex.Escape(fullAccountName) + @"$", RegexOptions.IgnoreCase))
{
accountIsAnAdmin = true;
break;
}
}
return accountIsAnAdmin;
}
///==========================================================================
/// IsApplicationRunAsAdmin
///==========================================================================
/// <summary>
/// Check if the application is run with elevated privilege, aka admin
/// </summary>
/// <param name=""></param>
/// <return>string</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static bool IsApplicationRunAsAdmin()
{
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
///==========================================================================
/// GetListOfMemberAccountsFromLocalGroups
///==========================================================================
/// <summary>
/// Get a list of member accounts from a local group
/// </summary>
/// <param name="groupName">Administrators, Guests, Users, etc</param>
/// <return>string</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 06/06/12 D.Le
///==========================================================================
public static List<string> GetListOfMemberAccountsFromLocalGroups(string groupName)
{
List<string> myItems = new List<string>();
using (DirectoryEntry machine = new DirectoryEntry("WinNT://" + Environment.MachineName))
{
//get local admin group
using (DirectoryEntry group = machine.Children.Find(groupName, "Group"))
{
//get all members of local admin group
object members = group.Invoke("Members", null);
foreach (object member in (IEnumerable)members)
{
//get account name
myItems.Add(new DirectoryEntry(member).Path);
}
}
}
return myItems;
}
///==========================================================================
/// IsUserInGroup
///==========================================================================
/// <summary>
/// Check if a particular user account is in local group
/// </summary>
/// <param name="fullQualifiedUsername">i.e.: US\1117637, ZTUAI362318\COEUser</param>
/// <param name="groupName">Administrators, etc</param>
/// <param name="errMsg"></param>
/// <return>true/false</return>
///==========================================================================
public static bool IsUserInGroup(string fullQualifiedUsername, string groupName, ref string errMsg)
{
bool isInGroup = false;
errMsg = "";
try
{
List<string> membersOfLocalAdminGroup = WindowsAdministration.GetListOfMemberAccountsFromLocalGroups(groupName);
fullQualifiedUsername = Regex.Replace(fullQualifiedUsername, @"\\", "/");
if (membersOfLocalAdminGroup.Any(member => Regex.IsMatch(member.ToString(), Regex.Escape(fullQualifiedUsername), RegexOptions.IgnoreCase)))
{
isInGroup = true;
}
}
catch (Exception ex)
{
errMsg = ex.Message;
}
return isInGroup;
}
///==========================================================================
/// AddUserToGroup
///==========================================================================
/// <summary>
/// Add an existing user account to a group
/// </summary>
/// <param name="userName">i.e.: 1117637</param>
/// <param name="userPassword"></param>
/// <param name="domain">US, etc</param>
/// <param name="groupName">Administrators, etc</param>
/// <param name="errMsg"></param>
/// <return>None</return>
///==========================================================================
public static void AddUserToGroup(string userName, string userPassword, string domain, string groupName, ref string errMsg)
{
bool impersonatingLoggedInUser = false;
PrincipalContext context = null;
GroupPrincipal group = null;
errMsg = "";
string appRunner = Environment.UserDomainName + "\\" + Environment.UserName;
try
{
context = new PrincipalContext(ContextType.Machine);
if (context != null)
group = GroupPrincipal.FindByIdentity(context, "Administrators");
if (group != null)
{
if (!String.IsNullOrEmpty(domain) && !String.Equals(domain, Environment.MachineName, StringComparison.CurrentCultureIgnoreCase))
{
if (!String.Equals(appRunner, GetWindowLoginID(), StringComparison.CurrentCultureIgnoreCase))
{
context = new PrincipalContext(ContextType.Domain, domain, userName, userPassword);
}
else
context = new PrincipalContext(ContextType.Domain, domain);
}
if (context != null)
{
if (!String.Equals(appRunner, GetWindowLoginID(), StringComparison.CurrentCultureIgnoreCase))
{
if (!Impersonate(userName, userPassword, domain))
errMsg = "Impersonation failed. Username or password is incorrect for: " + domain + "\\" + userName;
else
impersonatingLoggedInUser = true;
}
group.Members.Add(context, IdentityType.SamAccountName, userName);
if (impersonatingLoggedInUser)
UnImpersonate();
group.Save();
group.Dispose();
context.Dispose();
}
}
}
catch (Exception ex)
{
errMsg = ex.Message;
};
}
///==========================================================================
/// removeUserFromGroup
///==========================================================================
/// <summary>
/// Remove user from a group
/// </summary>
/// <param name="windowsLoginId">full qualified windows login id, i.e. DOMAIN\User</param>
/// <param name="groupName">name of the group, i.e. Administrators</param>
/// <param name="errMsg">error message</param>
/// <returns></returns>
///==========================================================================
public static void removeUserFromGroup(string windowsLoginId, string groupName, ref string errMsg)
{
string loginId = windowsLoginId;
loginId = Regex.Replace(loginId, @"\\", "/", RegexOptions.IgnoreCase);
try
{
using (DirectoryEntry machine = new DirectoryEntry("WinNT://" + Environment.MachineName))
{
//get local admin group
using (DirectoryEntry group = machine.Children.Find(groupName, "Group"))
{
//get all members of local admin group
object members = group.Invoke("Members", null);
foreach (object member in (IEnumerable)members)
{
using (var memberEntry = new DirectoryEntry(member))
{
if (!Regex.IsMatch(memberEntry.Path, @".+/" + Environment.MachineName + "/[^/]+$") && Regex.IsMatch(memberEntry.Path, loginId, RegexOptions.IgnoreCase))
{
group.Invoke("Remove", new[] { memberEntry.Path });
}
}
}
}
}
}
catch (Exception ex)
{
errMsg = ex.Message;
}
}
///==========================================================================
/// Impersonate
///==========================================================================
/// <summary>
/// Impersonate given logon information. Only can impersonate a regular
/// user. Cannot impersonate administrator if the UAC is set to Elevated
/// </summary>
/// <param name="logon">Windows logon name.</param>
/// <param name="password">password</param>
/// <param name="domain">domain name</param>
/// <returns></returns>
///==========================================================================
public static bool Impersonate(string logon, string password, string
domain)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (LogonUser(logon, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (null != impersonationContext) return true;
}
}
return false;
}
///==========================================================================
/// UnImpersonate
///==========================================================================
/// <summary>
/// Return to the original user account that starts up the program
/// </summary>
/// <param></param>
/// <returns></returns>
///==========================================================================
public static void UnImpersonate()
{
impersonationContext.Undo();
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LogonUser(
string lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll",
CharSet = System.Runtime.InteropServices.CharSet.Auto,
SetLastError = true)]
public extern static int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 4;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private static WindowsImpersonationContext impersonationContext;
}
}

View File

@@ -0,0 +1,467 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace CommonLib.Windows.Misc
{
public class WindowsRegistry
{
public enum valueKind { STRING, MULTI_STRING, DWORD, QWORD };
///==========================================================================
/// GetRegistryValueInString
///==========================================================================
/// <summary>
/// Get the value of a particular value name of a particular registry key
/// A registry value can be of many types, we have to convert them differently
/// into string
/// </summary>
/// <param name="registryPath">Registry folder path</param>
/// <param name="registryType">Local Machine, Classes Root, Current User</param>
/// <param name="valueName">the registry name that has a value associated with it</param>
/// <return>a string representing the value of the registry name</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 12/04/16 D.Le
///==========================================================================
public static string GetRegistryValueInString(string registryPath, RegistryHive registryType, string valueName)
{
string value = "";
var hklm = RegistryKey.OpenBaseKey(registryType, RegistryView.Registry64);
RegistryKey regSubKey = null;
regSubKey = hklm.OpenSubKey(registryPath, false);
registryPath = registryPath.Trim();
if (registryPath.Length > 0 && regSubKey != null && valueName.Length > 0)
{
List<string> list = new List<string>(regSubKey.GetValueNames());
if (list.FindIndex(x => x.Equals(valueName, StringComparison.OrdinalIgnoreCase)) != -1)
{
object obj = regSubKey.GetValue(valueName);
switch (regSubKey.GetValueKind(valueName))
{
case RegistryValueKind.String:
case RegistryValueKind.ExpandString:
value = (string)obj;
break;
case RegistryValueKind.Binary:
foreach (byte b in (byte[])obj)
{
if (value.Length == 0)
value = b.ToString("x2");
else
value += " " + b.ToString("x2");
}
Console.WriteLine();
break;
case RegistryValueKind.DWord:
value = Convert.ToString((Int32)obj);
break;
case RegistryValueKind.QWord:
value = Convert.ToString((Int64)obj);
break;
case RegistryValueKind.MultiString:
foreach (string s in (string[])obj)
{
if (value.Length == 0)
value = s;
else
value = "\n" + s;
}
break;
default:
break;
}
}
}
return value;
}
///==========================================================================
/// AddOrModifyRegistryKeySingleValue
///==========================================================================
/// <summary>
/// Add a value name/pair if the value name doesn't already exist for a particular
/// registry key. Otherwise, we modify the value of the value name.
/// </summary>
/// <param name="registryPath">Registry folder path</param>
/// <param name="registryType">Local Machine, Classes Root, Current User</param>
/// <param name="valueName">the registry name that has a value associated with it</param>
/// <param name="valueType">if the valueName doesn't exist, we need to create a new
/// value name of one of these types: string, dword, qword
/// </param>
/// <param name="value">the value to be assigned to the registry name</param>
/// <param name="errMsg">error message if the function execution fails</param>
/// <return>true/false as to the success/failure of the function execution</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 12/04/16 D.Le
///==========================================================================
public static bool AddOrModifyRegistryKeySingleValue(string registryPath, RegistryHive registryType, string valueName, RegistryValueKind valueType, string value, ref string errMsg)
{
bool successful = true;
errMsg = "";
var hklm = RegistryKey.OpenBaseKey(registryType, RegistryView.Registry64);
RegistryKey regSubKey = null;
registryPath = registryPath.Trim();
if (registryPath.Length > 0)
{
try
{
regSubKey = hklm.CreateSubKey(registryPath);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
}
else
{
errMsg = "Registry Path is empty";
successful = false;
}
if (successful && regSubKey != null && valueName.Length > 0)
{
List<string> list = new List<string>(regSubKey.GetValueNames());
// modify registry value
if (list.FindIndex(x => x.Equals(valueName, StringComparison.OrdinalIgnoreCase)) != -1)
{
object obj = regSubKey.GetValue(valueName);
valueType = regSubKey.GetValueKind(valueName);
}
switch (valueType)
{
case RegistryValueKind.String:
try
{
regSubKey.SetValue(valueName, value, RegistryValueKind.String);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
break;
case RegistryValueKind.DWord:
try
{
regSubKey.SetValue(valueName, value, RegistryValueKind.DWord);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
break;
case RegistryValueKind.QWord:
try
{
regSubKey.SetValue(valueName, value, RegistryValueKind.QWord);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
break;
default:
errMsg = "Unable to add value name of type " + valueType.ToString();
successful = false;
break;
}
}
if (regSubKey != null)
regSubKey.Close();
return successful;
}
///==========================================================================
/// AddOrModifyRegistryKeyMultiStringValue
///==========================================================================
/// <summary>
/// Add/modify a value name of type multi-string
/// </summary>
/// <param name="registryPath">Registry folder path</param>
/// <param name="registryType">Local Machine, Classes Root, Current User</param>
/// <param name="valueName">the registry name that has a value associated with it</param>
/// <param name="values">list of values</param>
/// <param name="errMsg">error message if the function execution fails</param>
/// <return>true/false as to the success/failure of the function execution</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 12/04/16 D.Le
///==========================================================================
public static bool AddOrModifyRegistryKeyMultiStringValue(string registryPath, RegistryHive registryType, string valueName, List<string> values, ref string errMsg)
{
bool successful = true;
errMsg = "";
var hklm = RegistryKey.OpenBaseKey(registryType, RegistryView.Registry64);
RegistryKey regSubKey = null;
registryPath = registryPath.Trim();
if (registryPath.Length > 0)
{
try
{
regSubKey = hklm.CreateSubKey(registryPath);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
}
else
{
errMsg = "Registry Path is empty";
successful = false;
}
if (successful && regSubKey != null && valueName.Length > 0)
{
try
{
regSubKey.SetValue(valueName, values.ToArray(), RegistryValueKind.MultiString);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
}
if (regSubKey != null)
regSubKey.Close();
return successful;
}
///==========================================================================
/// DeleteRegistryKey
///==========================================================================
/// <summary>
/// Delete registry key and all subkeys within it, recursively
/// </summary>
/// <param name="registryPath">Registry folder path</param>
/// <param name="registryType">Local Machine, Classes Root, Current User</param>
/// <param name="errMsg">error message if the function execution fails</param>
/// <return>true/false as to the success/failure of the function execution</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 12/04/16 D.Le
///==========================================================================
public static bool DeleteRegistryKey(string registryPath, RegistryHive registryType, ref string errMsg)
{
bool successful = true;
RegistryKey rkSubKey = null;
var hklm = RegistryKey.OpenBaseKey(registryType, RegistryView.Registry64);
registryPath = registryPath.Trim();
errMsg = "";
if (registryPath.Length > 0)
{
rkSubKey = hklm.OpenSubKey(registryPath, false);
if (rkSubKey == null)
{
errMsg = registryPath + " doesn't exist in registry";
}
}
else
{
errMsg = "Registry Path is empty";
successful = false;
}
if (successful && rkSubKey != null)
{
try
{
hklm.DeleteSubKeyTree(registryPath);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
}
if (rkSubKey != null)
rkSubKey.Close();
return successful;
}
///==========================================================================
/// DeleteRegistryValueName
///==========================================================================
/// <summary>
/// Delete a value name within a registry key
/// </summary>
/// <param name="registryPath">Registry folder path</param>
/// <param name="registryType">Local Machine, Classes Root, Current User</param>
/// <param name="valueName">the registry name to be deleted</param>
/// <param name="errMsg">error message if the function execution fails</param>
/// <return>true/false as to the success/failure of the function execution</return>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 12/04/16 D.Le
///==========================================================================
public static bool DeleteRegistryValueName(string registryPath, RegistryHive registryType, string valueName, ref string errMsg)
{
bool successful = true;
RegistryKey rkSubKey = null;
var hklm = RegistryKey.OpenBaseKey(registryType, RegistryView.Registry64);
bool valueNameExists = true;
registryPath = registryPath.Trim();
errMsg = "";
if (registryPath.Length > 0)
{
try
{
rkSubKey = hklm.OpenSubKey(registryPath, true);
if (rkSubKey == null)
{
errMsg = registryPath + " doesn't exist in registry";
}
else
{
List<string> list = new List<string>(rkSubKey.GetValueNames());
if (list.FindIndex(x => x.Equals(valueName, StringComparison.OrdinalIgnoreCase)) == -1)
{
errMsg = "Value name " + valueName + " doesn't exist in registry " + registryPath;
valueNameExists = false;
}
}
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
}
else
{
errMsg = "Registry Path is empty";
successful = false;
}
if (successful && rkSubKey != null && valueNameExists)
{
try
{
rkSubKey.DeleteValue(valueName);
}
catch (Exception e)
{
errMsg = e.Message;
successful = false;
}
}
if (rkSubKey != null)
rkSubKey.Close();
return successful;
}
///==========================================================================
/// GetRegistryDynamicUninstallKeys
///==========================================================================
/// <summary>
/// Get the registry keys (full path) for a particular software by using the
/// uninstall key. The uninstall keys for software are randomly generated.
/// So in order to get the key, we go through all the entries in the Uninstall
/// key to find the software name we are looking for. Under every uninstall
/// key, there's a valuename called DisplayName which corresponds to the name
/// of the software.
/// </summary>
/// <param name="registryType">Local Machine, Classes Root, Current User</param>
/// <param name="softwareName">the name of the software that is recorded in the registry</param>
///==========================================================================
/// Date Programmer Proj.ID SAR REVISION HISTORY:
/// --/--/-- ------------ -------- ---- --------------------------
/// 12/04/16 D.Le
///==========================================================================
public static List<string> GetRegistryDynamicUninstallKeys(RegistryHive registryType, string softwareName)
{
List<string> appUninstallKeys = new List<string>();
var hklm = RegistryKey.OpenBaseKey(registryType, RegistryView.Registry64);
string uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
for (int i = 1; i <= 2; i++)
{
if ( i==2)
uninstallKey = @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey rk = hklm.OpenSubKey(uninstallKey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
List<string> list = new List<string>(sk.GetValueNames());
if (list.FindIndex(x => x.Equals("DisplayName", StringComparison.OrdinalIgnoreCase)) != -1)
{
if (String.Equals(sk.GetValue("DisplayName").ToString(), softwareName, StringComparison.CurrentCultureIgnoreCase))
{
appUninstallKeys.Add(uninstallKey + @"\" + skName);
}
}
if ( sk != null)
sk.Close();
}
}
if ( rk != null )
rk.Close();
}
}
if ( hklm != null)
hklm.Close();
return appUninstallKeys;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DucCommonLibrary")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Northrop Grumman Corporation")]
[assembly: AssemblyProduct("DucCommonLibrary")]
[assembly: AssemblyCopyright("Copyright © Northrop Grumman Corporation 2013")]
[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("e082b05a-d65f-4778-8a4c-b056fc3e0737")]
// 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")]