diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -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
diff --git a/.gitignore b/.gitignore
index 7f91721..9491a2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/All_Purpose_Auto_Setup.csproj b/AllPurposeAutoSetup/All_Purpose_Auto_Setup.csproj
new file mode 100644
index 0000000..a47d656
--- /dev/null
+++ b/AllPurposeAutoSetup/All_Purpose_Auto_Setup.csproj
@@ -0,0 +1,211 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}
+ WinExe
+ Properties
+ All_Purpose_Auto_Setup
+ All_Purpose_Auto_Setup
+ v4.7.2
+ 512
+ false
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ sm3_setup.ico
+
+
+ app.manifest
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+ DLL\CommonLib.dll
+
+
+ packages\TaskScheduler.2.5.28\lib\net40\JetBrains.Annotations.dll
+
+
+ packages\TaskScheduler.2.5.28\lib\net40\Microsoft.Win32.TaskScheduler.dll
+ TaskSchedulerAlias
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ frmAbout.cs
+
+
+ Form
+
+
+ frmMain.cs
+
+
+ Form
+
+
+ frmSetupStatusDisplay.cs
+
+
+
+ Form
+
+
+ frmUserInput.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ frmAbout.cs
+ Designer
+
+
+ frmMain.cs
+ Designer
+
+
+ frmSetupStatusDisplay.cs
+
+
+ frmUserInput.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/All_Purpose_Auto_Setup.sln b/AllPurposeAutoSetup/All_Purpose_Auto_Setup.sln
new file mode 100644
index 0000000..c508992
--- /dev/null
+++ b/AllPurposeAutoSetup/All_Purpose_Auto_Setup.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34408.163
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "All_Purpose_Auto_Setup", "All_Purpose_Auto_Setup.csproj", "{8EFC377F-70B4-468B-BF30-B637C5857AA7}"
+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
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Debug|x64.ActiveCfg = Debug|x64
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Debug|x64.Build.0 = Debug|x64
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Release|x64.ActiveCfg = Release|x64
+ {8EFC377F-70B4-468B-BF30-B637C5857AA7}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {D478406A-C7B7-40FA-9C5B-9CD4D5AB67F1}
+ EndGlobalSection
+EndGlobal
diff --git a/AllPurposeAutoSetup/App.config b/AllPurposeAutoSetup/App.config
new file mode 100644
index 0000000..f7c13d4
--- /dev/null
+++ b/AllPurposeAutoSetup/App.config
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+ -1
+
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Common.cs b/AllPurposeAutoSetup/Common.cs
new file mode 100644
index 0000000..9ea1669
--- /dev/null
+++ b/AllPurposeAutoSetup/Common.cs
@@ -0,0 +1,339 @@
+// this alias is used for Microsoft.Win32.TaskScheduler.dll because
+// this dll defines the same type in the same namespace as the one defined in
+// mscorlib.dll, mainly namespace of System.Collection.Generic, and types: IReadOnlyList, IReadOnlyCollection.
+// By using this alias this the TaskScheduler dll, we avoid the
+// warning of conflict of the same type in the same namespace being defined in
+// more than one assemblies.
+extern alias TaskSchedulerAlias;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+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.Windows.Forms;
+
+using CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+using CommonLib.Windows.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class Common
+ {
+ delegate string GetWindowPathDelegate();
+
+ static Dictionary getWindowPathDel = new Dictionary(StringComparer.OrdinalIgnoreCase)
+ { { PathManip.enumWindowsDesignatedPaths.USER_DESKTOP.ToString(), PathManip.GetUserDesktopPath},
+ { PathManip.enumWindowsDesignatedPaths.USER_PROFILE.ToString(), PathManip.GetUserProfilePath},
+ { PathManip.enumWindowsDesignatedPaths.ALL_USER_DESKTOP.ToString(), PathManip.GetAllUserDesktopPath},
+ { PathManip.enumWindowsDesignatedPaths.USER_STARTUP_FOLDER.ToString(), PathManip.GetUserStartupFolderPath},
+ { PathManip.enumWindowsDesignatedPaths.ALL_USER_STARTUP_FOLDER.ToString(), PathManip.GetAllUserStartupFolderPath},
+ { PathManip.enumWindowsDesignatedPaths.USER_TEMP_FOLDER.ToString(), PathManip.GetUserTempPath}
+ };
+
+ public enum enum_SETUP_STEPS
+ {
+ NOT_VALID_STEP, // for initialization purposes
+ INSTALL_SOFTWARE_PACKAGES,
+ ENABLE_INTERNET_INFORMATION_SERVICES,
+ CREATE_DIRECTORIES,
+ CREATE_NETWORK_SHARES,
+ SET_ENVIRONMENT_VARIABLES,
+ SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS,
+ PROCESS_GUTS_CONFIG_FILE,
+ CREATE_WINDOWS_SHORTCUTS,
+ ASSIST_BUILDING_GUTS_APP,
+ TRANSFER_FILE_PACKAGES,
+ REMOVE_FILES_FOLDERS,
+ RUN_APPLICATIONS,
+ MODIFY_WINDOWS_REGISTRY,
+ CONFIGURE_NETWORK_ADAPTERS,
+ PROMPT_USER
+ }
+
+ public enum EXECUTION_STATUS
+ {
+ SUCCESS,
+ FAILURE,
+ SYSTEM_SKIP,
+ USER_SKIP // user decides to skip execution, in which cas, the action is neither successful or failed
+ }
+
+ public static bool pathContainsMacro(string path)
+ {
+ bool pathHasMacro = false;
+
+ foreach (PathManip.enumWindowsDesignatedPaths winPath in Enum.GetValues(typeof(PathManip.enumWindowsDesignatedPaths)))
+ {
+ string pattern = @"^\{" + winPath.ToString() + @"\}.*";
+
+ if (Regex.IsMatch(path, pattern, RegexOptions.IgnoreCase))
+ {
+ pathHasMacro = true;
+ break;
+ }
+ }
+
+ return pathHasMacro;
+ }
+
+ public static bool pathContainsCdDriveMacro(string path)
+ {
+ bool pathHasCdMacro = false;
+
+ Match regExMatch = Regex.Match(path, @"^\{([^\{\}]+)\}.*", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ if (String.Equals(regExMatch.Groups[1].Value, PathManip.enumWindowsDesignatedPaths.CD_DRIVE.ToString(), StringComparison.OrdinalIgnoreCase))
+ pathHasCdMacro = true;
+ }
+
+ return pathHasCdMacro;
+ }
+
+ public static string resolveMacroPath(string path)
+ {
+ string resolvedPath = path;
+ Match regExMatch;
+
+ regExMatch = Regex.Match(path, @"^\{([^\{\}]+)\}.*", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ if (getWindowPathDel.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ resolvedPath = Regex.Replace(path, @"\{([^\{\}]+)\}", getWindowPathDel[regExMatch.Groups[1].Value].Invoke(), RegexOptions.IgnoreCase);
+ }
+ // if cd drive macro is define then we have to process it a little bit differently, since there can be multiple cd drives in the system
+ else if (String.Equals(PathManip.enumWindowsDesignatedPaths.CD_DRIVE.ToString(), regExMatch.Groups[1].Value, StringComparison.OrdinalIgnoreCase))
+ {
+ resolvedPath = getValidatedCdPath(path);
+ }
+ }
+
+ return resolvedPath;
+ }
+
+ public static bool validatePathInCdDrive(string path, Form parentForm)
+ {
+ bool successful = true;
+ string msg = "";
+ DriveInfo drive = new DriveInfo(path.Substring(0, 1));
+ while (!drive.IsReady || (!File.Exists(path) && !Directory.Exists(path)))
+ {
+ Hardware.OpenCdDrive(drive.Name);
+
+ msg = ((frmSetupStatusDisplay)parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.OKCANCEL, null, "Please insert a disc into drive "
+ + drive.Name + " that has the following path:\n" + path + "\n\n Click OK to proceed", "Info", -1);
+
+ if (String.Equals(msg, "cancel", StringComparison.OrdinalIgnoreCase))
+ {
+ successful = false;
+ break;
+ }
+ }
+
+ return successful;
+ }
+
+ // if user specifies a path with a cd drive prefix macro (i.e. {cd_drive}\hey.txt, then we want to find the cd drive with the path (file or directory) specified
+ public static string getValidatedCdPath(string path = "")
+ {
+ string cdPath = "";
+ string emptyDrivePath = "";
+
+ List cdDrives = Hardware.GetAllCdDrives();
+
+ foreach (string drive in cdDrives)
+ {
+ if (path.Length == 0)
+ {
+ cdPath = drive;
+ break;
+ }
+ else
+ {
+ string tempPath = Regex.Replace(path, @"\{([^\{\}]+)\}", PathManip.RemoveTrailingSlashInPath(drive), RegexOptions.IgnoreCase);
+ DriveInfo driveInfo = new DriveInfo(tempPath.Substring(0, 1));
+
+ if (File.Exists(tempPath) || Directory.Exists(tempPath))
+ {
+ cdPath = tempPath;
+ break;
+ }
+ else if (!driveInfo.IsReady && emptyDrivePath.Length == 0)
+ {
+ emptyDrivePath = tempPath;
+ }
+ }
+ }
+
+ if (cdPath.Length == 0 && cdDrives.Count > 0)
+ {
+ if (emptyDrivePath.Length > 0)
+ cdPath = emptyDrivePath;
+ else
+ cdPath = Regex.Replace(path, @"\{([^\{\}]+)\}", PathManip.RemoveTrailingSlashInPath(cdDrives[0]), RegexOptions.IgnoreCase);
+ }
+
+ return cdPath;
+ }
+
+ // return indentation in spaces
+ public static string getIndentation(int indentMultiples)
+ {
+ string indentUnit = " ";
+ string indentation = String.Empty;
+
+ for (int i = 1; i <= indentMultiples; i++)
+ indentation += indentUnit;
+
+ return indentation;
+ }
+
+ public static Color getSetupStatusColor(EXECUTION_STATUS status)
+ {
+ if (status == EXECUTION_STATUS.SUCCESS)
+ return Color.Green;
+ else if (status == EXECUTION_STATUS.FAILURE)
+ return Color.Red;
+ else
+ return Color.FromArgb(224, 154, 14);
+ }
+
+ public static Color getSetupStepTitleColor()
+ {
+ return Color.FromArgb(125, 143, 128);
+ }
+
+ public static void formatConfigIniFailureMessage(string message, List textPropList)
+ {
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.textColor = getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 10);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(message, "File:");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(message, "Section:");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ if (StringManip.GetPhraseWordIndexInText(message, "Key:") > -1)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(message, "Key:");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+
+ if (StringManip.GetPhraseWordIndexInText(message, "Value:") > -1)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(message, "Value:");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(message, "Description:") - 1;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+
+ public static void enableAutoRunAfterReboot(string taskSchedulerName, string appPath)
+ {
+ Properties.Settings.Default["AutoRunOnStartup"] = true;
+
+ createTaskSchedulerForAutoRunAfterReboot(taskSchedulerName, appPath);
+ }
+
+ private static void createTaskSchedulerForAutoRunAfterReboot(string taskSchedulerName, string appPath)
+ {
+ using (TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskService ts = new TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskService())
+ {
+ if (ts.GetTask(taskSchedulerName) == null)
+ {
+ TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskDefinition td = ts.NewTask();
+ td.RegistrationInfo.Description = taskSchedulerName;
+
+ // when running task, use the following account
+ td.Principal.UserId = String.Concat(Environment.UserDomainName, "\\", Environment.UserName);
+
+ // only run after user has logged on
+ td.Principal.LogonType = TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskLogonType.InteractiveToken;
+
+ // run this task with highest privileges
+ td.Principal.RunLevel = TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest;
+
+ // creating the trigger, this actually executes the task
+ TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.LogonTrigger trigger = new TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.LogonTrigger();
+ trigger.UserId = String.Concat(Environment.UserDomainName, "\\", Environment.UserName);
+ trigger.Delay = TimeSpan.FromSeconds(60.0);
+ td.Triggers.Add(trigger);
+
+ td.Actions.Add(new TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.ExecAction(appPath, null, null));
+ ts.RootFolder.RegisterTaskDefinition(taskSchedulerName, td);
+ }
+ }
+ }
+
+ public static void deleteTaskSchedulerForAutoRunAfterReboot(string taskSchedulerName)
+ {
+ using (TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskService ts = new TaskSchedulerAlias::Microsoft.Win32.TaskScheduler.TaskService())
+ {
+ if (ts.GetTask(taskSchedulerName) != null)
+ {
+ ts.RootFolder.DeleteTask(taskSchedulerName);
+ }
+ }
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/ConfigFileManager.cs b/AllPurposeAutoSetup/ConfigFileManager.cs
new file mode 100644
index 0000000..1fffcb4
--- /dev/null
+++ b/AllPurposeAutoSetup/ConfigFileManager.cs
@@ -0,0 +1,502 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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 CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class ConfigFileManager
+ {
+ // each of the enumeration in here should match a section name in the INI file
+ public enum enum_INI_SECTION_NAMES
+ {
+ General,
+ Global_Settings,
+ GUTS_Info,
+ Install_Software,
+ Paths_Creation,
+ Paths_Sharing,
+ Env_Variables,
+ Setup_Step_Manager,
+ GUTS_Pre_Build_Assistance,
+ Files_Transfer_Packages,
+ GUTS_Config_File,
+ Windows_Shortcuts,
+ Files_Folders_Removal,
+ Run_Applications,
+ Windows_Features,
+ Windows_Registry
+ }
+
+ // this is used to verify INI file and flag errors in the INI file for user to fix
+ public struct Ini_KeyValue
+ {
+ public string iniSectionName;
+ public string iniKeyName;
+ public string iniValue;
+ public T alternateValue; // user-defined value, this could be a bool, int, anything
+
+ public Ini_KeyValue(T tvar)
+ {
+ iniSectionName = String.Empty;
+ iniKeyName = String.Empty;
+ iniValue = String.Empty;
+ alternateValue = tvar;
+ }
+ }
+
+ public struct ConfigGeneralInfo
+ {
+ public IniFileManip iniFile;
+ public string pathAndNameOfConfigFile;
+
+ public bool is64BitPlatform;
+ public bool is32BitPlatform;
+
+ public Ini_KeyValue programName;
+ public Ini_KeyValue applicationPlatform;
+ }
+
+ public struct ConfigGlobalSettings
+ {
+ public Ini_KeyValue suppressAllPrompts;
+ }
+
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ //public event Action> UpdateStatusDisplayAndLogEvent;
+
+ Form m_parentForm;
+ public static ConfigGeneralInfo ms_configGeneralInfo;
+ public static ConfigGlobalSettings ms_configGlobalSettings;
+
+ public ConfigFileManager(Form parentForm, string configFile)
+ {
+ m_parentForm = parentForm;
+
+ ms_configGeneralInfo.pathAndNameOfConfigFile = configFile;
+ ms_configGeneralInfo.programName = new Ini_KeyValue("");
+ ms_configGeneralInfo.applicationPlatform = new Ini_KeyValue("");
+
+ ms_configGeneralInfo.is32BitPlatform = false;
+ ms_configGeneralInfo.is64BitPlatform = false;
+
+ ms_configGeneralInfo.iniFile = new IniFileManip(ms_configGeneralInfo.pathAndNameOfConfigFile);
+
+ ms_configGlobalSettings.suppressAllPrompts = new Ini_KeyValue(false);
+
+ parseConfigInfo();
+ }
+
+ private void parseConfigInfo()
+ {
+ readGeneralSection(ms_configGeneralInfo.iniFile);
+ readGlobalSection(ms_configGeneralInfo.iniFile);
+ }
+
+ public static void parseConfigInfo(string iniSectionName, List> configInfo)
+ {
+ string[] keyDataPair;
+ string[] sectionData;
+ Ini_KeyValue iniVal = new Ini_KeyValue("");
+
+ if (configInfo == null)
+ configInfo = new List>();
+
+ sectionData = ms_configGeneralInfo.iniFile.ReadSectionData(iniSectionName);
+ foreach (string line in sectionData)
+ {
+ keyDataPair = line.Split('=');
+
+ if (keyDataPair.Length == 2)
+ {
+ iniVal.iniSectionName = iniSectionName;
+ iniVal.iniKeyName = keyDataPair[0];
+ iniVal.iniValue = keyDataPair[1];
+
+ configInfo.Add(iniVal) ;
+ }
+ }
+ }
+
+ public static void parseConfigInfo(string iniSectionName, Dictionary configInfo)
+ {
+ string[] keyDataPair;
+ string[] sectionData;
+
+ if (configInfo == null)
+ configInfo = new Dictionary();
+
+ sectionData = ms_configGeneralInfo.iniFile.ReadSectionData(iniSectionName);
+ foreach (string line in sectionData)
+ {
+ keyDataPair = line.Split('=');
+
+ if (keyDataPair.Length == 2)
+ configInfo[keyDataPair[0]] = keyDataPair[1];
+ }
+ }
+
+ public void readGeneralSection(IniFileManip iniFile)
+ {
+ string[] keyDataPair;
+ Dictionary keyAndValuePair = new Dictionary();
+ Dictionary keyAndValuePair2 = new Dictionary();
+ Ini_KeyValue bIniVal = new Ini_KeyValue(false);
+ Ini_KeyValue iniVal = new Ini_KeyValue("");
+ Ini_KeyValue iniVal2 = new Ini_KeyValue("");
+
+ string sectionName;
+
+ string[] sectionData;
+
+ sectionName = enum_INI_SECTION_NAMES.General.ToString();
+ sectionData = iniFile.ReadSectionData(sectionName);
+
+ ms_configGeneralInfo.programName.iniKeyName = "program_name";
+ ms_configGeneralInfo.programName.iniSectionName = sectionName;
+
+ ms_configGeneralInfo.applicationPlatform.iniKeyName = "Application_Platform";
+ ms_configGeneralInfo.applicationPlatform.iniSectionName = sectionName;
+
+ foreach (string line in sectionData)
+ {
+ keyDataPair = line.Split('=');
+
+ if (String.Equals(keyDataPair[0], ms_configGeneralInfo.programName.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ if (keyDataPair.Length == 2)
+ {
+ ms_configGeneralInfo.programName.iniValue = keyDataPair[1];
+ }
+ }
+ else if (String.Equals(keyDataPair[0], ms_configGeneralInfo.applicationPlatform.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ if (keyDataPair.Length == 2)
+ {
+ ms_configGeneralInfo.applicationPlatform.iniValue = keyDataPair[1];
+ }
+ if (String.Equals(ms_configGeneralInfo.applicationPlatform.iniValue, "32", StringComparison.OrdinalIgnoreCase))
+ ms_configGeneralInfo.is32BitPlatform = true;
+ else if (String.Equals(ms_configGeneralInfo.applicationPlatform.iniValue, "64", StringComparison.OrdinalIgnoreCase))
+ ms_configGeneralInfo.is64BitPlatform = true;
+ else
+ ms_configGeneralInfo.is64BitPlatform = true;
+ }
+ }
+ }
+
+ public void readGlobalSection(IniFileManip iniFile)
+ {
+ string[] keyDataPair;
+ Dictionary keyAndValuePair = new Dictionary();
+ Dictionary keyAndValuePair2 = new Dictionary();
+ Ini_KeyValue bIniVal = new Ini_KeyValue(false);
+ Ini_KeyValue iniVal = new Ini_KeyValue("");
+ Ini_KeyValue iniVal2 = new Ini_KeyValue("");
+
+ string sectionName;
+
+ string[] sectionData;
+
+ sectionName = enum_INI_SECTION_NAMES.Global_Settings.ToString();
+ sectionData = iniFile.ReadSectionData(sectionName);
+
+ ms_configGlobalSettings.suppressAllPrompts.iniKeyName = "Suppress_All_Prompts";
+ ms_configGlobalSettings.suppressAllPrompts.iniSectionName = sectionName;
+
+ foreach (string line in sectionData)
+ {
+ keyDataPair = line.Split('=');
+
+ if (String.Equals(keyDataPair[0], ms_configGlobalSettings.suppressAllPrompts.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ if (keyDataPair.Length == 2)
+ {
+ ms_configGlobalSettings.suppressAllPrompts.iniValue = keyDataPair[1];
+ }
+
+ if (String.Equals(ms_configGlobalSettings.suppressAllPrompts.iniValue, "true", StringComparison.OrdinalIgnoreCase)
+ ||
+ String.Equals(ms_configGlobalSettings.suppressAllPrompts.iniValue, "yes", StringComparison.OrdinalIgnoreCase))
+ ms_configGlobalSettings.suppressAllPrompts.alternateValue = true;
+ else
+ ms_configGlobalSettings.suppressAllPrompts.alternateValue = false;
+ }
+ }
+ }
+
+ public static void readOneToManyDictionary(IniFileManip iniFile, string sectionName, string leftDictPattern, string rightDictPattern, Dictionary, List>> dict)
+ {
+ string[] keyDataPair, splitStrings, splitStrings2;
+ Match regExMatch;
+ Dictionary keyAndValuePair = new Dictionary();
+ Dictionary keyAndValuePair2 = new Dictionary();
+ Ini_KeyValue bIniVal = new Ini_KeyValue(false);
+ Ini_KeyValue iniVal = new Ini_KeyValue("");
+ Ini_KeyValue iniVal2 = new Ini_KeyValue("");
+
+ string[] sectionData;
+
+ string iniEntryDelimiter = "[ini_entry_separator]";
+ string iniKeyValueDelimiter = "[key_value_separator]";
+
+ sectionData = iniFile.ReadSectionData(sectionName);
+ foreach (string line in sectionData)
+ {
+ keyDataPair = line.Split('=');
+
+ if (keyDataPair.Length == 2)
+ keyDataPair[1] = Regex.Replace(keyDataPair[1], @"\{equal_sign\}", "=");
+
+ regExMatch = Regex.Match(keyDataPair[0], leftDictPattern, RegexOptions.IgnoreCase);
+
+ // if item belongs to the left side of the dictionary
+ if (regExMatch.Success && keyDataPair.Length == 2)
+ {
+ // if there's not already an item that exists in the dictionary
+ if (!keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value) && keyDataPair[1].Length > 0)
+ {
+ // generate the key information
+ iniVal.iniSectionName = sectionName;
+ iniVal.iniKeyName = keyDataPair[0];
+ iniVal.iniValue = keyDataPair[1];
+
+ // if there are items on the right of the dictionary that's associated with the item on the left side
+ if (keyAndValuePair2.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ splitStrings = keyAndValuePair2[regExMatch.Groups[1].Value].Split(new string[] { iniEntryDelimiter }, StringSplitOptions.RemoveEmptyEntries);
+
+ foreach (string keyValuePairItem in splitStrings)
+ {
+ splitStrings2 = keyValuePairItem.Split(new string[] { iniKeyValueDelimiter }, StringSplitOptions.None);
+
+ // generate value information
+ iniVal2.iniSectionName = sectionName;
+ iniVal2.iniKeyName = splitStrings2[0];
+ iniVal2.iniValue = splitStrings2[1];
+
+ if (dict.ContainsKey(iniVal))
+ dict[iniVal].Add(iniVal2);
+ else
+ dict[iniVal] = new List>() { iniVal2 };
+
+ if (!keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ keyAndValuePair[regExMatch.Groups[1].Value] = keyDataPair[0] + iniKeyValueDelimiter + keyDataPair[1];
+ }
+ }
+
+ keyAndValuePair2.Remove(regExMatch.Groups[1].Value);
+ }
+ else // store the Ini struct of the left hand side of the dictionary
+ keyAndValuePair[regExMatch.Groups[1].Value] = keyDataPair[0] + iniKeyValueDelimiter + keyDataPair[1];
+ }
+ }
+ else
+ {
+ regExMatch = Regex.Match(keyDataPair[0], rightDictPattern, RegexOptions.IgnoreCase);
+
+ // if the item belong to the right side of the dictionary
+ if (regExMatch.Success && keyDataPair.Length == 2)
+ {
+ // is this key/value is associated with the corresponding value of the left hand side of the dictionary
+ if (keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ // get the ini properties of the left side of the dictionary
+ splitStrings2 = keyAndValuePair[regExMatch.Groups[1].Value].Split(new string[] { iniKeyValueDelimiter }, StringSplitOptions.RemoveEmptyEntries);
+
+ // generate the key information
+ iniVal.iniSectionName = sectionName;
+ iniVal.iniKeyName = splitStrings2[0];
+ iniVal.iniValue = splitStrings2[1];
+
+ // generate value information
+ iniVal2.iniSectionName = sectionName;
+ iniVal2.iniKeyName = keyDataPair[0];
+ iniVal2.iniValue = keyDataPair[1];
+
+ // save the key/value for this app name
+ if (dict.ContainsKey(iniVal))
+ dict[iniVal].Add(iniVal2);
+ else
+ dict[iniVal] = new List>() { iniVal2 };
+ }
+ else
+ {
+ if (keyAndValuePair2.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ keyAndValuePair2[regExMatch.Groups[1].Value] += iniEntryDelimiter + keyDataPair[0] + iniKeyValueDelimiter + keyDataPair[1];
+ }
+ else
+ keyAndValuePair2[regExMatch.Groups[1].Value] = keyDataPair[0] + iniKeyValueDelimiter + keyDataPair[1];
+ }
+ }
+ }
+ }
+
+ if (keyAndValuePair.Count > 0)
+ {
+ // remove entries in keyAndValuePair that have already been saved in the dictionary
+ foreach (KeyValuePair, List>> entry in dict)
+ {
+ regExMatch = Regex.Match(entry.Key.iniKeyName, leftDictPattern, RegexOptions.IgnoreCase);
+ // if item belongs to the left side of the dictionary
+ if (regExMatch.Success)
+ {
+ if (keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value))
+ keyAndValuePair.Remove(regExMatch.Groups[1].Value);
+ }
+ }
+
+ // for each group of items, if only the left side of the dictionary is defined, add it to the dictionary anyway
+ foreach (KeyValuePair entry in keyAndValuePair)
+ {
+ // break down the elements of the left side of dictionary
+ splitStrings2 = entry.Value.Split(new string[] { iniKeyValueDelimiter }, StringSplitOptions.RemoveEmptyEntries);
+
+ // generate the key information
+ iniVal.iniSectionName = sectionName;
+ iniVal.iniKeyName = splitStrings2[0];
+ iniVal.iniValue = splitStrings2[1];
+
+ if (!dict.ContainsKey(iniVal))
+ dict[iniVal] = new List>();
+ }
+ }
+ }
+
+ public void readOneToOneDictionary(IniFileManip iniFile, string sectionName, string leftDictPattern, string rightDictPattern, Dictionary, Ini_KeyValue> dict)
+ {
+ string[] keyDataPair, splitStrings2;
+ Match regExMatch;
+ Dictionary keyAndValuePair = new Dictionary();
+ Dictionary keyAndValuePair2 = new Dictionary();
+ Ini_KeyValue bIniVal = new Ini_KeyValue(false);
+ Ini_KeyValue iniVal = new Ini_KeyValue("");
+ Ini_KeyValue iniVal2 = new Ini_KeyValue("");
+
+ string[] sectionData;
+
+ sectionData = iniFile.ReadSectionData(sectionName);
+ foreach (string path in sectionData)
+ {
+ keyDataPair = path.Split('=');
+
+ if (keyDataPair.Length == 2)
+ keyDataPair[1] = Regex.Replace(keyDataPair[1], @"\{equal_sign\}", "=");
+
+ regExMatch = Regex.Match(keyDataPair[0], leftDictPattern, RegexOptions.IgnoreCase);
+
+ // if item belongs to the left side of the dictionary
+ if (regExMatch.Success && keyDataPair.Length == 2)
+ {
+ // if there's not an existing item already in the dictionary
+ if (!keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ // if the item on the right side is associated to the item on the left side of the dictionary
+ if (keyAndValuePair2.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ // generate the key information
+ iniVal.iniSectionName = sectionName;
+ iniVal.iniKeyName = keyDataPair[0];
+ iniVal.iniValue = keyDataPair[1];
+
+ splitStrings2 = keyAndValuePair2[regExMatch.Groups[1].Value].Split('|');
+
+ // generate the value information
+ iniVal2.iniSectionName = sectionName;
+ iniVal2.iniKeyName = splitStrings2[0];
+ iniVal2.iniValue = splitStrings2[1];
+
+ dict[iniVal] = iniVal2;
+ keyAndValuePair2.Remove(regExMatch.Groups[1].Value);
+ }
+ else
+ keyAndValuePair[regExMatch.Groups[1].Value] = keyDataPair[0] + "|" + keyDataPair[1];
+ }
+ }
+
+ regExMatch = Regex.Match(keyDataPair[0], rightDictPattern, RegexOptions.IgnoreCase);
+
+ // if item belongs to the right side of the dictionary
+ if (regExMatch.Success && keyDataPair.Length == 2)
+ {
+ // if item on the left is associated with the item on the right side of the dictionary
+ if (keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value))
+ {
+ // get the ini properties of the left side of the dictionary
+ splitStrings2 = keyAndValuePair[regExMatch.Groups[1].Value].Split('|');
+
+ // generate the key information
+ iniVal.iniSectionName = sectionName;
+ iniVal.iniKeyName = splitStrings2[0];
+ iniVal.iniValue = splitStrings2[1];
+
+ // generate the value information
+ iniVal2.iniSectionName = sectionName;
+ iniVal2.iniKeyName = keyDataPair[0];
+ iniVal2.iniValue = keyDataPair[1];
+
+ // create a new entry in the dictionary
+ dict[iniVal] = iniVal2;
+ }
+ else
+ {
+ keyAndValuePair2[regExMatch.Groups[1].Value] = keyDataPair[0] + "|" + keyDataPair[1];
+ }
+ }
+ }
+
+ if (keyAndValuePair.Count > 0)
+ {
+ // remove entries in keyAndValuePair that have already been saved in the dictionary
+ foreach (KeyValuePair, ConfigFileManager.Ini_KeyValue> entry in dict)
+ {
+ regExMatch = Regex.Match(entry.Key.iniKeyName, leftDictPattern, RegexOptions.IgnoreCase);
+ // if item belongs to the left side of the dictionary
+ if (regExMatch.Success)
+ {
+ if (keyAndValuePair.ContainsKey(regExMatch.Groups[1].Value))
+ keyAndValuePair.Remove(regExMatch.Groups[1].Value);
+ }
+ }
+
+ // for each group of items, if only the left side of the dictionary is defined, add it to the dictionary anyway
+ foreach (KeyValuePair entry in keyAndValuePair)
+ {
+ // break down the elements of the left side of dictionary
+ splitStrings2 = entry.Value.Split('|');
+
+ // generate the key information
+ iniVal.iniSectionName = sectionName;
+ iniVal.iniKeyName = splitStrings2[0];
+ iniVal.iniValue = splitStrings2[1];
+
+ iniVal2.iniSectionName = "";
+ iniVal2.iniKeyName = "";
+ iniVal2.iniValue = "";
+
+ if (!dict.ContainsKey(iniVal))
+ dict[iniVal] = iniVal2;
+ }
+ }
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/DLL/CommonLib.dll b/AllPurposeAutoSetup/DLL/CommonLib.dll
new file mode 100644
index 0000000..91e2e33
Binary files /dev/null and b/AllPurposeAutoSetup/DLL/CommonLib.dll differ
diff --git a/AllPurposeAutoSetup/Docs/Automated Windows Installer (AWI) - SDD.pptx b/AllPurposeAutoSetup/Docs/Automated Windows Installer (AWI) - SDD.pptx
new file mode 100644
index 0000000..308bb22
Binary files /dev/null and b/AllPurposeAutoSetup/Docs/Automated Windows Installer (AWI) - SDD.pptx differ
diff --git a/AllPurposeAutoSetup/DotNet2Pt0FrameworkManager.cs b/AllPurposeAutoSetup/DotNet2Pt0FrameworkManager.cs
new file mode 100644
index 0000000..fb07ea9
--- /dev/null
+++ b/AllPurposeAutoSetup/DotNet2Pt0FrameworkManager.cs
@@ -0,0 +1,285 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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 CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class DotNet2Pt0FrameworkManager
+ {
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+
+ Form m_parentForm;
+
+ private bool dotNetSecurityZoneSettingSuccessful;
+
+ public DotNet2Pt0FrameworkManager(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ // modify trust levels for security zones
+ public bool adjustZoneSecurityForDotNetFrameWork2Pt0(string sectionName)
+ {
+ bool setupSuccessful = true;
+ string indentation = String.Empty, platformStr;
+
+ string dotNetFrameWork2_32bit_Path = @"C:\Windows\Microsoft.NET\Framework\v2.0.50727";
+ string dotNetFrameWork2_64bit_Path = @"C:\Windows\Microsoft.NET\Framework64\v2.0.50727";
+ string dotNetFrameWork2_Bin_Path;
+ string caspolApp = String.Empty;
+
+ List securityZoneNames = new List() { "My_Computer_Zone", "LocalIntranet_Zone", "Internet_Zone", "Trusted_Zone", "Restricted_Zone" };
+ List trustLevels = new List() { "FullTrust", "LocalIntranet", "Internet", "Nothing" };
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ string msg;
+
+ if (ConfigFileManager.ms_configGeneralInfo.is32BitPlatform)
+ {
+ platformStr = "32-bit";
+ dotNetFrameWork2_Bin_Path = dotNetFrameWork2_32bit_Path;
+ }
+ else
+ {
+ platformStr = "64-bit";
+ dotNetFrameWork2_Bin_Path = dotNetFrameWork2_64bit_Path;
+ }
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=Setting .NET Framework 2.0 (" + platformStr + ") Security Zone Trust Level=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ if (setupSuccessful)
+ {
+ caspolApp = dotNetFrameWork2_Bin_Path + "\\caspol.exe";
+
+ if (!Directory.Exists(dotNetFrameWork2_32bit_Path))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. .NET Framework 2.0 (" + platformStr + ") is not installed.";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.ERROR, null, "Unable to detect the presence .NET Framework 2.0 (" + platformStr + ").\n\n Please install .NET Framework 2.0 before continuing...", "ERROR!!!", -1);
+ setupSuccessful = false;
+ }
+ else if (!File.Exists(caspolApp))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. " + caspolApp + " not found.";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.ERROR, null, "Unable to detect the presence .NET Framework 2.0 (" + platformStr + ").\n\n Please install .NET Framework 2.0 before continuing...", "ERROR!!!", -1);
+ setupSuccessful = false;
+ }
+ else
+ {
+ dotNetSecurityZoneSettingSuccessful = false;
+ ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
+ cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
+ cmdStartInfo.RedirectStandardOutput = true;
+ cmdStartInfo.RedirectStandardError = true;
+ cmdStartInfo.RedirectStandardInput = true;
+ cmdStartInfo.UseShellExecute = false;
+ cmdStartInfo.CreateNoWindow = true;
+
+ Process cmdProcess;
+ //cmdProcess.StandardInput.WriteLine("Dism /online /disable-feature /featurename:IIS-FTPSvc /norestart"); //Execute command
+
+ cmdProcess = new Process();
+ cmdProcess.StartInfo = cmdStartInfo;
+ cmdProcess.ErrorDataReceived += cmd_Error;
+ cmdProcess.OutputDataReceived += cmd_SecurityZone_DataReceived;
+ cmdProcess.EnableRaisingEvents = true;
+ cmdProcess.Start();
+ cmdProcess.BeginOutputReadLine();
+ cmdProcess.BeginErrorReadLine();
+
+ // turn prompts off
+ cmdProcess.StandardInput.WriteLine(caspolApp + " -pp off"); //Execute command
+
+ cmdProcess.StandardInput.WriteLine("exit"); //Execute exit.
+
+ cmdProcess.WaitForExit();
+ cmdProcess.Close();
+
+ if (!dotNetSecurityZoneSettingSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. Access denied from running .NET Framework Caspol 2.0.";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.ERROR, null, "Access denied from running .NET Framework Caspol 2.0.\n\n Make sure to run application as Administrator...", "ERROR!!!", -1);
+ setupSuccessful = false;
+ }
+
+ foreach (string zone in securityZoneNames)
+ {
+ cmdProcess = new Process();
+ cmdProcess.StartInfo = cmdStartInfo;
+ cmdProcess.ErrorDataReceived += cmd_Error;
+ cmdProcess.OutputDataReceived += cmd_SecurityZone_DataReceived;
+ cmdProcess.EnableRaisingEvents = true;
+ cmdProcess.Start();
+ cmdProcess.BeginOutputReadLine();
+ cmdProcess.BeginErrorReadLine();
+
+ dotNetSecurityZoneSettingSuccessful = false;
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "" + zone + "=" + trustLevels[0];
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set trust level for security zone
+ cmdProcess.StandardInput.WriteLine(caspolApp + " -m -cg " + zone + " " + trustLevels[0]); //Execute command
+ //cmdProcess.StandardInput.WriteLine("");
+
+ //count++;
+
+ cmdProcess.StandardInput.WriteLine("exit"); //Execute exit.
+
+ cmdProcess.WaitForExit();
+ cmdProcess.Close();
+
+ if (dotNetSecurityZoneSettingSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = " - FAILED";
+ setupSuccessful = false;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+
+ cmdProcess = new Process();
+ cmdProcess.StartInfo = cmdStartInfo;
+ //cmdProcess.ErrorDataReceived += cmd_Error;
+ //cmdProcess.OutputDataReceived += cmd_SecurityZone_DataReceived;
+ cmdProcess.EnableRaisingEvents = true;
+ cmdProcess.Start();
+ cmdProcess.BeginOutputReadLine();
+ cmdProcess.BeginErrorReadLine();
+
+ // turn policy change prompt back on. THIS IS VERY IMPORTANT
+ // if this is not turned back on, the Windows Firewall might block some functionality of an application
+ cmdProcess.StandardInput.WriteLine(caspolApp + " -pp on"); //Execute command
+
+ cmdProcess.StandardInput.WriteLine("exit"); //Execute exit.
+
+ cmdProcess.WaitForExit();
+ cmdProcess.Close();
+ }
+ }
+ return setupSuccessful;
+ }
+
+ void cmd_SecurityZone_DataReceived(object sender, DataReceivedEventArgs e)
+ {
+ Match regExMatch;
+
+ if (e.Data == null)
+ {
+ return;
+ }
+
+ regExMatch = Regex.Match(e.Data, @".*success.*", RegexOptions.IgnoreCase);
+ if (regExMatch.Success)
+ {
+ dotNetSecurityZoneSettingSuccessful = true;
+ }
+ }
+
+ void cmd_Error(object sender, DataReceivedEventArgs e)
+ {
+ //Console.WriteLine("Error from other process");
+ //Console.WriteLine(e.Data);
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/FileFolderRemovalManager.cs b/AllPurposeAutoSetup/FileFolderRemovalManager.cs
new file mode 100644
index 0000000..44a72ec
--- /dev/null
+++ b/AllPurposeAutoSetup/FileFolderRemovalManager.cs
@@ -0,0 +1,350 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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.Xml;
+using System.Xml.XPath;
+using System.Net;
+
+using CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class FileFolderRemovalManager
+ {
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+
+ public event Action> UpdateStatusDisplayAtLine;
+
+ public List> filesFoldersToBeRemoved = new List>();
+
+ Form m_parentForm;
+
+ public FileFolderRemovalManager(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ public bool removeFilesFolders(string sectionName)
+ {
+ bool setupSuccessful = true;
+ string msg, indentation = String.Empty, displayMsg = "", logMsg = "";
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 10;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=Removing Files/Folders=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ filesFoldersToBeRemoved.Clear();
+
+ parseConfigInfo(sectionName);
+
+ if (setupSuccessful)
+ {
+ int filesDeletedCount = 0, foldersDeletedCount = 0, filesSkipped = 0, foldersSkipped = 0;
+ frmSetupStatusDisplay displayFrm = (frmSetupStatusDisplay)m_parentForm;
+ int itemCountLineIndex = displayFrm.updateStatusDisplayAndLog("\n ", "", textPropList);
+ int deleteItemLineIndex = displayFrm.updateStatusDisplayAndLog("\n ", "", textPropList);
+
+ List filesAndFoldersToBeRemoved = new List();
+
+ foreach (ConfigFileManager.Ini_KeyValue item in filesFoldersToBeRemoved)
+ {
+ string path = "";
+ path = Path.GetFullPath(Common.resolveMacroPath(item.iniValue));
+
+ if (File.Exists(path))
+ {
+ filesAndFoldersToBeRemoved.Add(path);
+ }
+ else if (Directory.Exists(path))
+ {
+ // delete folder recursively
+ if (item.alternateValue)
+ {
+ filesAndFoldersToBeRemoved.Add(path);
+ }
+ else
+ {
+ string[] files = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
+ filesAndFoldersToBeRemoved.AddRange(files.ToList());
+ }
+ }
+ else
+ {
+ string what = "";
+
+ if (PathManip.PathIsFile(path))
+ {
+ filesSkipped++;
+ what = "File";
+ }
+ else
+ {
+ foldersSkipped++;
+ what = "Folder";
+ }
+
+ indentation = Common.getIndentation(1);
+ logMsg = "\n" + indentation + "Deleting " + path + " - SKIPPED. " + what + " does not exist";
+ UpdateStatusDisplayAndLogEvent("", logMsg, textPropList);
+ }
+
+ }
+
+ foreach (string item in filesAndFoldersToBeRemoved)
+ {
+ indentation = Common.getIndentation(1);
+ msg = indentation + "Files Deleted: " + filesDeletedCount.ToString() + " Folders Deleted: " + foldersDeletedCount.ToString();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = 2;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont.FontFamily, 10, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "Folders deleted:");
+ textProp.wordCount = 2;
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "Folders deleted:") + 2;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont.FontFamily, 10, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAtLine(msg, itemCountLineIndex, textPropList);
+
+ //tempTextPropList = new List(textPropList);
+
+ if (File.Exists(item) || Directory.Exists(item))
+ {
+ displayMsg = indentation + "Deleting " + StringManip.ShortenStringToSize(item, 65);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ //textProp.textColor = Color.FromArgb(157, 150, 19);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 1;
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(255, 60, 0);
+ textProp.wordIndex = 1;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAtLine(displayMsg, deleteItemLineIndex, textPropList);
+
+ if (Directory.Exists(item))
+ {
+ try
+ {
+ PathManip.DeleteFoldersRecursive(item);
+ foldersDeletedCount++;
+ logMsg = "\n" + indentation + "Deleting " + item + " - SUCCESS";
+ }
+ catch (Exception e)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ displayMsg = "\n" + indentation + "- FAILED. Error deleting folder\n" + indentation + "Folder: " + item + "\n" + indentation + "Error description: " + e.Message;
+ logMsg = "\n" + indentation + "Deleting " + item + " - FAILED";
+ setupSuccessful = false;
+ }
+ }
+ else
+ {
+ try
+ {
+ File.SetAttributes(item, FileAttributes.Normal);
+ File.Delete(item);
+ filesDeletedCount++;
+ logMsg = "\n" + indentation + "Deleting " + item + " - SUCCESS";
+ }
+ catch (Exception e)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ displayMsg = "\n" + indentation + "- FAILED. Error deleting file\n" + indentation + "File: " + item + "\n" + indentation + "Error description: " + e.Message;
+ logMsg = "\n" + indentation + "Deleting " + item + " - FAILED";
+ setupSuccessful = false;
+ }
+ }
+
+ if (!setupSuccessful)
+ {
+ break;
+ }
+
+ UpdateStatusDisplayAndLogEvent("", logMsg, textPropList);
+ }
+
+ Thread.Sleep(2000);
+ }
+
+ // delete the very first line that is the start of the progress update
+ // all the lines below the first starting lines will get deleted too
+ for (int i = 1; i <= 2; i++)
+ {
+ displayFrm.removeStatusDisplayLine(itemCountLineIndex, true);
+ }
+
+ if (!setupSuccessful)
+ {
+ UpdateStatusDisplayAndLogEvent(displayMsg, logMsg, textPropList);
+ }
+
+ if (setupSuccessful)
+ {
+ if (filesFoldersToBeRemoved.Count == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- SKIPPED. No file/folder to delete";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- SUCCESS. (Files Deleted: " + filesDeletedCount + " ) (Folders Deleted: " + foldersDeletedCount + " )" + " (Files skipped: " + filesSkipped + " )" + " (Folders skipped: " + foldersSkipped + " )";
+ UpdateStatusDisplayAndLogEvent(msg, "", textPropList);
+ }
+ }
+
+ msg = "\n" + Common.getIndentation(1) + "Files Deleted: " + filesDeletedCount + " | Folders Deleted: " + foldersDeletedCount + " | Files Skipped: " + filesSkipped + " | Folders Skipped: " + foldersSkipped;
+ UpdateStatusDisplayAndLogEvent("", msg, textPropList);
+
+ }
+
+ return setupSuccessful;
+ }
+
+ private void parseConfigInfo(string sectionName)
+ {
+ string[] keyDataPair;
+ Match regExMatch;
+ ConfigFileManager.Ini_KeyValue bIniVal = new ConfigFileManager.Ini_KeyValue(false);
+
+ string[] sectionData;
+
+ sectionData = ConfigFileManager.ms_configGeneralInfo.iniFile.ReadSectionData(sectionName);
+
+ foreach (string path in sectionData)
+ {
+ keyDataPair = path.Split('=');
+
+ if (keyDataPair.Length == 2)
+ {
+ bIniVal.iniSectionName = sectionName;
+ bIniVal.iniKeyName = keyDataPair[0];
+ bIniVal.iniValue = keyDataPair[1];
+
+ regExMatch = Regex.Match(bIniVal.iniValue, @"^([^,]+),.*recursive.*", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ bIniVal.alternateValue = true;
+ bIniVal.iniValue = regExMatch.Groups[1].Value;
+ }
+ else
+ bIniVal.alternateValue = false;
+
+ filesFoldersToBeRemoved.Add(bIniVal);
+ }
+ }
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/FilePackageTransferManager.cs b/AllPurposeAutoSetup/FilePackageTransferManager.cs
new file mode 100644
index 0000000..ccdda17
--- /dev/null
+++ b/AllPurposeAutoSetup/FilePackageTransferManager.cs
@@ -0,0 +1,1945 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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.Xml;
+using System.Xml.XPath;
+using System.Net;
+
+using CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class FilePackageTransferManager
+ {
+ public enum eFileAction
+ {
+ None
+ };
+ public enum eFileCopyStatus { FAIL, SUCCESS };
+
+ public enum eCopyType { FOLDERS, FILES };
+
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+
+ public event Action> UpdateStatusDisplayAtLine;
+
+ // event for thread to notify other threads that it has exited
+ private AutoResetEvent _resetEvent = new AutoResetEvent(false);
+
+ public List> fileTransferPackages = new List>();
+
+ private List sourceFiles = new List();
+
+ FileManip.FileDownloadProgressTracker downloadProgressTracker = new FileManip.FileDownloadProgressTracker();
+
+ int m_copyProgressLineIndex = 0;
+
+ Form m_parentForm;
+
+ bool m_filePackageProcessedSuccessful = false;
+
+ int m_fileCreatedCount = 0;
+
+ int m_fileCopyCount = 0;
+
+ public FilePackageTransferManager(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ public bool manageFilePackageTransfer(string sectionName)
+ {
+ bool setupSuccessful = true;
+ string msg, indentation = String.Empty;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 10;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=Copying File Packages=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ XPathDocument doc = null;
+
+ fileTransferPackages.Clear();
+
+ ConfigFileManager.parseConfigInfo(sectionName, fileTransferPackages);
+
+ setupSuccessful = verifyFilePackagesInfo();
+
+ if (setupSuccessful)
+ {
+ foreach (ConfigFileManager.Ini_KeyValue filePackage in fileTransferPackages)
+ {
+ try
+ {
+ XmlReaderSettings readerSettings = new XmlReaderSettings();
+ // tells the xmlreader to ignore comment in XML file
+ readerSettings.IgnoreComments = true;
+ using (XmlReader reader = XmlReader.Create(filePackage.iniValue, readerSettings))
+ {
+ // load the XML file
+ doc = new XPathDocument(reader);
+ }
+ }
+ catch (Exception e)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. Unable to parse file " + filePackage.iniValue + ". " + e.Message;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+
+ if (setupSuccessful)
+ {
+ XPathNavigator nav = doc.CreateNavigator();
+
+ // move to root node
+ nav.MoveToRoot();
+
+ // move to 1st level node
+ if (nav.MoveToFirstChild())
+ {
+ // move to 2nd level node
+ if (nav.MoveToFirstChild())
+ {
+ if (!ProcessXML2ndLevelNodes(nav, Path.GetDirectoryName(filePackage.iniValue)))
+ {
+ setupSuccessful = false;
+ }
+ }
+ }
+ }
+
+ if (!setupSuccessful)
+ break;
+ }
+
+ if (setupSuccessful)
+ {
+ if (!m_filePackageProcessedSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- SKIPPED. Nothing to be copied from the provided information.";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+ }
+ }
+ return setupSuccessful;
+ }
+
+ private void DownloadProgressHandler(UInt64 totalBytesCopied, UInt64 totalBytesFile)
+ {
+ string totalSizeDescription = FileManip.DescribeFileSize(totalBytesFile, FileManip.eFileSizeResolution.AUTO);
+ double totalPercentageReceived = ((double)totalBytesCopied / (double)totalBytesFile) * 100;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ if (!downloadProgressTracker.stopwatchForFileDownload.IsRunning)
+ {
+ downloadProgressTracker.stopwatchForFileDownload.Start();
+ }
+
+ if (!downloadProgressTracker.stopwatchForUpdateInterval.IsRunning)
+ {
+ downloadProgressTracker.stopwatchForUpdateInterval.Start();
+ }
+
+ // when an interval is reached, update download progress
+ if (downloadProgressTracker.stopwatchForUpdateInterval.ElapsedMilliseconds >= downloadProgressTracker.updateIntervalInMs)
+ {
+ downloadProgressTracker.stopwatchForUpdateInterval.Reset();
+
+ if (downloadProgressTracker.averageBytesReceivedPerUpdateInterval == 0)
+ downloadProgressTracker.averageBytesReceivedPerUpdateInterval = totalBytesCopied - downloadProgressTracker.totalBytesReceived;
+ else
+ {
+ downloadProgressTracker.averageBytesReceivedPerUpdateInterval += totalBytesCopied - downloadProgressTracker.totalBytesReceived;
+ downloadProgressTracker.averageBytesReceivedPerUpdateInterval /= 2;
+ }
+ downloadProgressTracker.totalBytesReceived = totalBytesCopied;
+
+ downloadProgressTracker.millisecondsCount += downloadProgressTracker.updateIntervalInMs;
+
+ string receivedSizeDescription = FileManip.DescribeFileSize(totalBytesCopied, downloadProgressTracker.fileSizeResolution);
+
+ if (downloadProgressTracker.strTotalBytesReceived.Length > 0)
+ {
+ // determine what the highest resolution transfer rate change
+ FileManip.eFileSizeResolution res = FileManip.GetFileResolutionOfTransferRate(receivedSizeDescription, downloadProgressTracker.strTotalBytesReceived);
+ // increate the count for this resolution
+ downloadProgressTracker.unitCount[res]++;
+ }
+
+ // every 2 seconds, we determine which resolution change the most, and use the resolution
+ // that's changed the most as the update progress
+ if (downloadProgressTracker.millisecondsCount >= 2000)
+ {
+ FileManip.eFileSizeResolution res = downloadProgressTracker.getResolutionWithHighestCount();
+
+ if (res != FileManip.eFileSizeResolution.AUTO)
+ downloadProgressTracker.fileSizeResolution = res;
+
+ downloadProgressTracker.millisecondsCount = 0;
+ downloadProgressTracker.resetUnitCount();
+ }
+
+ receivedSizeDescription = FileManip.DescribeFileSize(totalBytesCopied, downloadProgressTracker.fileSizeResolution);
+
+ downloadProgressTracker.strTotalBytesReceived = receivedSizeDescription;
+
+ // shorten the size description
+ receivedSizeDescription = FileManip.ShortenFileSizeDescription(receivedSizeDescription);
+
+ long downloadSpeed = (long)Math.Ceiling((double)downloadProgressTracker.averageBytesReceivedPerUpdateInterval / ((double)downloadProgressTracker.updateIntervalInMs / 1000.0));
+ string downloadSpeedDesc = FileManip.DescribeFileSize((UInt64)downloadSpeed, FileManip.eFileSizeResolution.AUTO);
+ downloadSpeedDesc = Regex.Replace(downloadSpeedDesc, @"(\d+)\.\d+(.+)", "$1$2", RegexOptions.IgnoreCase);
+
+ string msg = Common.getIndentation(1) + "Progress: " + string.Format("{0:N2}%", totalPercentageReceived) +
+ " Speed: " + downloadSpeedDesc + "/s Copied: " + receivedSizeDescription + " Total Size: " + totalSizeDescription +
+ " Elapsed time: " + DateTimeManip.DescribeTimeElapsed(downloadProgressTracker.stopwatchForFileDownload.Elapsed);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(0, 82, 204);
+ textProp.wordIndex = 1;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(0, 82, 204);
+ textProp.wordIndex = 3;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(0, 82, 204);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "copied:") + 1;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "total size:") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(0, 82, 204);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "total size:") + 2;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(0, 82, 204);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "elapsed time:") + 2;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAtLine(msg, m_copyProgressLineIndex, textPropList);
+ }
+ }
+
+ bool processFilePackage()
+ {
+ bool setupSuccessful = true;
+ string msg = "", msg2 = "", displayMsg = "", logMsg = "", indentation = String.Empty, errMsg = "", sourcePath = "", destPath = "", tempMsg = "";
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+ List tempTextPropList;
+
+ bool overwriteDestinationFile = false;
+ bool overwriteDestinationFileAlways = false;
+ bool promptForOverwriteConfirmation = true;
+
+ frmSetupStatusDisplay displayFrm = (frmSetupStatusDisplay)m_parentForm;
+
+ int fileCountLineIndex = displayFrm.updateStatusDisplayAndLog("\n ", "", textPropList);
+ int sourceFileLineIndex = displayFrm.updateStatusDisplayAndLog("\n ", "", textPropList);
+ int destFileLineIndex = displayFrm.updateStatusDisplayAndLog("\n ", "", textPropList);
+ m_copyProgressLineIndex = displayFrm.updateStatusDisplayAndLog("\n ", "", textPropList);
+
+ foreach (SourceFile file in sourceFiles)
+ {
+ indentation = Common.getIndentation(1);
+ msg = indentation + "Files Copied: " + m_fileCopyCount.ToString() + " Files Created: " + m_fileCreatedCount.ToString();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = 2;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont.FontFamily, 10, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "files created:");
+ textProp.wordCount = 2;
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(5, 112, 1);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "files created:") + 2;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont.FontFamily, 10, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAtLine(msg, fileCountLineIndex, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ //textProp.textColor = Color.FromArgb(157, 150, 19);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 1;
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(255, 60, 0);
+ textProp.wordIndex = 1;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ tempTextPropList = new List(textPropList);
+
+ sourcePath = file.SourcePath;
+ destPath = file.destPath;
+
+ if (sourcePath.Length > 0 && !PathManip.PathContainsAtLeastOneFolder(sourcePath))
+ sourcePath = PathManip.AddTrailingSlashToPath(sourcePath);
+
+ if (!PathManip.PathContainsAtLeastOneFolder(destPath))
+ destPath = PathManip.AddTrailingSlashToPath(destPath);
+
+ string destFileName;
+ // get the actual path and filename letter casing
+ string sourceFilePathAndName = PathManip.GetProperFilePathCapitalization(Path.Combine(sourcePath, file.FileName));
+ string sourceFileName = Path.GetFileName(sourceFilePathAndName);
+ string sourceFilePath = Path.GetDirectoryName(sourceFilePathAndName);
+
+ // if the source file is to be save as a different at the destination
+ if (file.FileNameSaveAs.Length > 0)
+ destFileName = file.FileNameSaveAs;
+ else
+ destFileName = sourceFileName;
+
+ indentation = Common.getIndentation(1);
+ if (file.SourcePath.Length > 0)
+ {
+ msg = indentation + "Copying " + StringManip.ShortenStringToSize(sourceFilePathAndName, 65);
+ msg2 = indentation + "To " + StringManip.ShortenStringToSize(Path.Combine(destPath, destFileName), 65);
+ }
+ else
+ msg = indentation + "Creating " + StringManip.ShortenStringToSize(Path.Combine(destPath, destFileName), 65);
+
+ UpdateStatusDisplayAtLine(msg, sourceFileLineIndex, textPropList);
+
+ if (msg2.Length > 0)
+ {
+ textPropList = new List(tempTextPropList);
+ UpdateStatusDisplayAtLine(msg2, destFileLineIndex, textPropList);
+ }
+
+ if (file.individualOverwrite.Length != 0)
+ {
+ promptForOverwriteConfirmation = false;
+ if (String.Equals(file.individualOverwrite, "yes", StringComparison.OrdinalIgnoreCase) || String.Equals(file.individualOverwrite, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ overwriteDestinationFile = true;
+ }
+ else
+ overwriteDestinationFile = false;
+ }
+
+ if (promptForOverwriteConfirmation && File.Exists(Path.Combine(destPath, destFileName)))
+ {
+ MessageBoxCustom.clsCustomButton button1 = new MessageBoxCustom.clsCustomButton("YES - This File", "YesOneTime");
+ MessageBoxCustom.clsCustomButton button2 = new MessageBoxCustom.clsCustomButton("NO - This File", "NoOneTime");
+ MessageBoxCustom.clsCustomButton button3 = new MessageBoxCustom.clsCustomButton("YES - All Files", "YesAlways");
+ MessageBoxCustom.clsCustomButton button4 = new MessageBoxCustom.clsCustomButton("No - All Files", "NoAlways");
+
+ List options = new List() { button1, button2, button3, button4 };
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.CUSTOMQUESTION, options,
+ "File " + Path.Combine(destPath, destFileName) + "\nalready exists. Would you like to overwrite?", "Warning!!!", -1);
+
+ if (String.Equals(msg, "YesOneTime", StringComparison.OrdinalIgnoreCase))
+ {
+ overwriteDestinationFile = true;
+ }
+ else if (String.Equals(msg, "YesAlways", StringComparison.OrdinalIgnoreCase))
+ {
+ overwriteDestinationFileAlways = true;
+ overwriteDestinationFile = true;
+ promptForOverwriteConfirmation = false;
+ }
+ else if (String.Equals(msg, "NoAlways", StringComparison.OrdinalIgnoreCase))
+ {
+ promptForOverwriteConfirmation = false;
+ }
+ }
+
+ if (m_fileCopyCount == 0 && m_fileCreatedCount == 0)
+ UpdateStatusDisplayAtLine(indentation + "Initializing. Please wait...", m_copyProgressLineIndex, textPropList);
+
+ // if the file to be created already exists
+ if (file.SourcePath.Length == 0 && File.Exists(Path.Combine(destPath, destFileName)))
+ {
+ logMsg = "\n" + Common.getIndentation(2) + "Create " + Path.Combine(destPath, destFileName) + " - SKIPPED. File already exists at destination";
+ }
+ else if (file.SourcePath.Length > 0 && File.Exists(Path.Combine(destPath, destFileName)) && !overwriteDestinationFile)
+ {
+ logMsg = "\n" + Common.getIndentation(2) + "Copy " + sourceFilePathAndName + " --> " + Path.Combine(destPath, destFileName) + " - SKIPPED. File already exists at destination";
+ }
+ else
+ {
+ foreach (var drive in DriveInfo.GetDrives()
+ .Where(d => d.DriveType == DriveType.CDRom))
+ {
+ if (Regex.IsMatch(sourceFilePathAndName, @"^" + Regex.Escape(PathManip.RemoveTrailingSlashInPath(drive.Name)) + @".*", RegexOptions.IgnoreCase))
+ {
+ while (!drive.IsReady || !File.Exists(sourceFilePathAndName))
+ {
+ Hardware.OpenCdDrive(drive.Name);
+
+ tempMsg = "Please insert a disc";
+
+ if (file.cdLabel.Length > 0)
+ tempMsg += " labeled \"" + file.cdLabel + "\"";
+
+ tempMsg += " into drive " + drive.Name + " that has the following file:\n" + sourceFilePathAndName + "\n\n Click OK to proceed";
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.OKCANCEL, null,
+ tempMsg, "Info", -1);
+
+ if (String.Equals(msg, "cancel", StringComparison.OrdinalIgnoreCase))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+
+ logMsg = "\n" + Common.getIndentation(2) + "Copy " + sourceFilePathAndName + " --> " + Path.Combine(destPath, destFileName) + " - FAILED";
+ displayMsg = "\n" + indentation + "- FAILED. Unable to locate file: " + sourceFilePathAndName;
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ if (FileManip.CopyFileWithProgress(sourceFilePath, sourceFileName, file.destPath, destFileName,
+ true, FileAttributes.Normal,
+ new FileManip.FileCopyProgressChangeDelegate(DownloadProgressHandler), downloadProgressTracker))
+ {
+ indentation = Common.getIndentation(2);
+ if (file.SourcePath.Length > 0)
+ {
+ logMsg = "\n" + indentation + "Copy " + sourceFilePathAndName + " --> " + Path.Combine(destPath, destFileName) + " - SUCCESS";
+ m_fileCopyCount++;
+ }
+ else
+ {
+ logMsg = "\n" + indentation + "Create " + Path.Combine(destPath, destFileName) + " - SUCCESS";
+ m_fileCreatedCount++;
+ }
+ }
+ else
+ {
+ errMsg = downloadProgressTracker.errorMsg;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+
+ if (file.SourcePath.Length > 0)
+ {
+ logMsg = "\n" + Common.getIndentation(2) + "Copy " + sourceFilePathAndName + " --> " + Path.Combine(destPath, destFileName) + " - FAILED";
+ displayMsg = "\n" + indentation + "- FAILED. Copying file failed. " + Regex.Replace(errMsg, @"\r\n", "", RegexOptions.IgnoreCase) + "\n" + indentation + "From: " + sourceFilePathAndName + "\n" + indentation + "To: " + Path.Combine(destPath, destFileName);
+ }
+ else
+ {
+ logMsg = "\n" + Common.getIndentation(2) + "Create " + Path.Combine(destPath, destFileName) + " - FAILED";
+ displayMsg = "\n" + indentation + "- FAILED. Creating file failed. " + Regex.Replace(errMsg, @"\r\n", "", RegexOptions.IgnoreCase) + "\n" + indentation + "File to be created: " + Path.Combine(destPath, destFileName);
+ }
+
+ setupSuccessful = false;
+ }
+ }
+ }
+
+ // blank out the line
+ displayFrm.removeStatusDisplayLine(fileCountLineIndex, false);
+
+ // blank out the line
+ displayFrm.removeStatusDisplayLine(m_copyProgressLineIndex, false);
+
+ if (!overwriteDestinationFileAlways)
+ overwriteDestinationFile = false;
+
+ if (!setupSuccessful)
+ {
+ break;
+ }
+
+ UpdateStatusDisplayAndLogEvent("", logMsg, textPropList);
+ }
+
+ for (int i = 1; i <= 4; i++)
+ {
+ // delete the very first line that is the start of the progress update
+ // all the lines below the first starting lines will get deleted too
+ displayFrm.removeStatusDisplayLine(fileCountLineIndex, true);
+ }
+
+ if (!setupSuccessful)
+ {
+ UpdateStatusDisplayAndLogEvent(displayMsg, logMsg, textPropList);
+ }
+
+ return setupSuccessful;
+ }
+
+ ///===================================================================================
+ /// ProcessXML2ndLevelNodes
+ ///===================================================================================
+ ///
+ /// Process the child nodes of the 2nd level node
+ /// in the XML file.
+ ///
+ /// navigator object for traversing XML tree
+ ///
+ /// info about software package in source control
+ ///
+ /// file actions associated with source files
+ /// file name to be saved as at destination
+ /// backgroundworker
+ /// backgroundworker event arguments
+ /// true if processing node successfully, otherwise false
+ ///===================================================================================
+ private bool ProcessXML2ndLevelNodes(XPathNavigator nav, string defaultStartingSourcePath)
+ {
+ bool setupSuccessful = true;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ string msg, indentation = String.Empty;
+ string startingSourcePath = "";
+ Match regexMatch;
+
+ if (nav == null)
+ setupSuccessful = false;
+
+ SourceFile sourceFile = new SourceFile("");
+
+ if (setupSuccessful)
+ {
+ do
+ {
+ string packageName = nav.GetAttribute("name", String.Empty);
+
+ if (packageName.Length == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. Attribute \"name\" not found or has invalid value in node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(233, 31, 195);
+ textProp.wordIndex = 3;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Copying File Package " + packageName;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+
+ string customStartingSourcePath = nav.GetAttribute("startingsourcepath", string.Empty);
+ string startingDestPath = nav.GetAttribute("startingdestpath", string.Empty);
+
+ // match macro defined in the value of they key, macro is in the form of {xxxxx} such as {user_desktop}, {user_temp_folder}, {cd_drive}
+ regexMatch = Regex.Match(customStartingSourcePath, @"^\{([^\{\}]+)\}.*", RegexOptions.IgnoreCase);
+
+ // if rootpath is ., then we take the path of the XML package as the root path
+ if (string.Equals(customStartingSourcePath, "."))
+ customStartingSourcePath = defaultStartingSourcePath;
+ else if (regexMatch.Success)
+ {
+ if (Common.pathContainsMacro(regexMatch.Groups[0].Value))
+ {
+ string resolvedPath = Common.resolveMacroPath(regexMatch.Groups[0].Value);
+
+ if (Common.pathContainsCdDriveMacro(regexMatch.Groups[0].Value))
+ {
+ if (resolvedPath.Length == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. " + regexMatch.Groups[0].Value + " macro was defined. But no CD drive is found in the system" + ". XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+
+ sourceFile.cdLabel = nav.GetAttribute("cdlabel", string.Empty);
+ }
+
+ customStartingSourcePath = resolvedPath;
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"startingsourcepath\" specifies an invalid macro in the path. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ if (setupSuccessful && customStartingSourcePath.Length > 0)
+ {
+ // if path is not absolute path
+ if (!Path.IsPathRooted(customStartingSourcePath) && !Regex.IsMatch(customStartingSourcePath, @"^\{([^\{\}]+)\}", RegexOptions.IgnoreCase))
+ customStartingSourcePath = Path.GetFullPath(Path.Combine(defaultStartingSourcePath, customStartingSourcePath));
+
+ if (!Hardware.IsCdDrive(customStartingSourcePath) && !Directory.Exists(customStartingSourcePath))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"startingsourcepath\" specifies a path that does not exist. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ // match macro defined in the value of they key, macro is in the form of {xxxxx} such as {user_desktop}, {user_temp_folder}, {cd_drive}
+ regexMatch = Regex.Match(startingDestPath, @"^\{([^\{\}]+)\}.*", RegexOptions.IgnoreCase);
+
+ if (regexMatch.Success)
+ {
+ if (Common.pathContainsMacro(regexMatch.Groups[0].Value))
+ {
+ string resolvedPath = Common.resolveMacroPath(regexMatch.Groups[0].Value);
+
+ if (Common.pathContainsCdDriveMacro(regexMatch.Groups[0].Value))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. " + regexMatch.Groups[0].Value + " macro is not allowed to be specified for attribute \"startingdestpath\"" + ". XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+
+ startingDestPath = resolvedPath;
+
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"startingdestpath\" specifies an invalid macro in the path. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+ // if path is not absolute path
+ else if (startingDestPath.Length > 0 && !Path.IsPathRooted(startingDestPath))
+ startingDestPath = Path.GetFullPath(Path.Combine(defaultStartingSourcePath, startingDestPath));
+
+ if (!Directory.Exists(startingDestPath))
+ {
+ if (startingDestPath.Length > 0)
+ {
+ if (!PathManip.PathIsWritable(startingDestPath))
+ setupSuccessful = false;
+ }
+ else
+ setupSuccessful = false;
+
+ if (!setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ if (startingDestPath.Length == 0)
+ msg = "\n" + indentation + "- FAILED. Attribute \"startingdestpath\" is missing or has no value. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ else
+ msg = "\n" + indentation + "- FAILED. Attribute \"startingdestpath\" specifies a path that is invalid or not accessible. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ break;
+ }
+ }
+
+ if (customStartingSourcePath.Length > 0)
+ startingSourcePath = customStartingSourcePath;
+
+ // move to 3rd level node
+ if (nav.MoveToFirstChild())
+ {
+ m_fileCreatedCount = 0;
+ m_fileCopyCount = 0;
+ if (!ProcessXML3rdLevelNodes(nav, defaultStartingSourcePath, startingSourcePath, startingDestPath, sourceFile))
+ setupSuccessful = false;
+
+ // move back to 2nd level node
+ nav.MoveToParent();
+ }
+
+ if (setupSuccessful)
+ {
+ if (!m_filePackageProcessedSuccessful)
+ m_filePackageProcessedSuccessful = true;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+
+ if (m_fileCreatedCount == 0 && m_fileCopyCount == 0)
+ {
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ msg = " - SKIPPED. (Files Created: " + m_fileCreatedCount + " ) " + "(Files Copied: " + m_fileCopyCount + " ) ";
+ }
+ else
+ {
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ msg = " - SUCCESS. (Files Created: " + m_fileCreatedCount + " ) " + "(Files Copied: " + m_fileCopyCount + " ) ";
+ }
+ textPropList.Add(textProp);
+ UpdateStatusDisplayAndLogEvent(msg, "", textPropList);
+
+ msg = "\n" + Common.getIndentation(2) + "Total Files Created: " + m_fileCreatedCount + " | Total Files Copied: " + m_fileCopyCount;
+ UpdateStatusDisplayAndLogEvent("", msg, textPropList);
+ }
+
+ if (!setupSuccessful)
+ break;
+ }
+
+ } while (nav.MoveToNext()); // move to next software package
+ }
+
+ return setupSuccessful;
+ }
+
+ ///===================================================================================
+ /// ProcessXML3rdLevelNodes
+ ///===================================================================================
+ ///
+ /// Process the child nodes of the 3rd level node
+ /// in the XML file.
+ ///
+ /// navigator object for traversing XML tree
+ ///
+ ///
+ ///
+ /// true if processing node successfully, otherwise false
+ ///===================================================================================
+ private bool ProcessXML3rdLevelNodes(XPathNavigator nav, string defaultStartingSourcePath, string startingSourcePath, string startingDestPath, SourceFile sourceFile)
+ {
+ bool setupSuccessful = true;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ string msg, indentation = String.Empty, errMsg = "", tempStr = "";
+
+ Match regExMatch;
+
+ eCopyType copyType = eCopyType.FILES;
+
+ do
+ {
+ sourceFiles.Clear();
+ sourceFile.SourcePath = "";
+ sourceFile.destPath = "";
+
+ if (string.Equals(nav.Name, "filescopy", StringComparison.CurrentCultureIgnoreCase))
+ {
+ copyType = eCopyType.FILES;
+ }
+ else if (string.Equals(nav.Name, "folderscopy", StringComparison.CurrentCultureIgnoreCase))
+ {
+ copyType = eCopyType.FOLDERS;
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Invalid tag name specified. XML Node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+
+ // do not force sourcedir to be specified to allow user to be able to create a new file at the destination
+ sourceFile.SourcePath = nav.GetAttribute("sourcedir", string.Empty);
+ sourceFile.SourcePath = sourceFile.SourcePath.Trim(' ');
+
+ // match macro defined in the value of they key, macro is in the form of {xxxxx} such as {user_desktop}, {user_temp_folder}, {cd_drive}
+ regExMatch = Regex.Match(sourceFile.SourcePath, @"^\{([^\{\}]+)\}.*", RegexOptions.IgnoreCase);
+
+ if (string.Equals(sourceFile.SourcePath, "."))
+ {
+ if (startingSourcePath.Length > 0)
+ sourceFile.SourcePath = startingSourcePath;
+ else
+ sourceFile.SourcePath = defaultStartingSourcePath;
+ }
+ else if (regExMatch.Success)
+ {
+ if (Common.pathContainsMacro(regExMatch.Groups[0].Value))
+ {
+ string resolvedPath = Common.resolveMacroPath(regExMatch.Groups[0].Value);
+
+ if (Common.pathContainsCdDriveMacro(regExMatch.Groups[0].Value))
+ {
+ if (resolvedPath.Length == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. " + regExMatch.Groups[0].Value + " macro was defined. But no CD drive is found in the system" + ". XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ sourceFile.SourcePath = resolvedPath;
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"sourcedir\" specifies an invalid macro in the path. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ tempStr = nav.GetAttribute("cdlabel", string.Empty);
+
+ if (tempStr.Length > 0)
+ {
+ sourceFile.cdLabel = tempStr;
+ }
+
+ if (sourceFile.SourcePath.Length > 0)
+ {
+ // if path is not absolute path
+ if (!Path.IsPathRooted(sourceFile.SourcePath))
+ {
+ if (startingSourcePath.Length > 0)
+ {
+ if (!PathManip.PathContainsAtLeastOneFolder(startingSourcePath))
+ startingSourcePath = PathManip.AddTrailingSlashToPath(startingSourcePath);
+
+ sourceFile.SourcePath = Path.GetFullPath(Path.Combine(startingSourcePath, sourceFile.SourcePath));
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"sourcedir\" cannot specify a relative path here since there's no absolute path defined in the parent node. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+ }
+
+ if (setupSuccessful && sourceFile.SourcePath.Length > 0 && !Hardware.IsCdDrive(sourceFile.SourcePath) && !Directory.Exists(sourceFile.SourcePath))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+
+ // the directory exists but the account being used by application is denied access
+ if (PathManip.DirectoryVisible(sourceFile.SourcePath, ref errMsg))
+ {
+ msg = "\n" + indentation + "- FAILED. " + errMsg + ".";
+
+ if (PathManip.PathIsNetworkPath(sourceFile.SourcePath))
+ {
+ msg += "\n" + indentation + "This error is caused by the fact that this application is run as an account that does not have access privileges to the network path. "
+ + "\n" + indentation + "Run this application using an account that is allowed by the network path you're trying to access. XML Node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ }
+ }
+ else
+ {
+ msg = "\n" + indentation + "- FAILED. Attribute \"sourcedir\" specifies a relative/absolute path that does not exist in file system. XML Node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ setupSuccessful = false;
+ break;
+
+ }
+
+ sourceFile.destPath = nav.GetAttribute("destdir", string.Empty).TrimEnd('\\');
+ sourceFile.destPath = sourceFile.destPath.Trim(' ');
+
+ // match macro defined in the value of they key, macro is in the form of {xxxxx} such as {user_desktop}, {user_temp_folder}, {cd_drive}
+ regExMatch = Regex.Match(sourceFile.destPath, @"^\{([^\{\}]+)\}.*", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ if (Common.pathContainsMacro(regExMatch.Groups[0].Value))
+ {
+ string resolvedPath = Common.resolveMacroPath(regExMatch.Groups[0].Value);
+
+ if (Common.pathContainsCdDriveMacro(regExMatch.Groups[0].Value))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. " + regExMatch.Groups[0].Value + " macro is not allowed to be specified for attribute \"destdir\"" + ". XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+
+ sourceFile.destPath = resolvedPath;
+
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"destdir\" specifies an invalid macro in the path. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+ else if (string.Equals(sourceFile.destPath, "."))
+ {
+ if (startingDestPath.Length > 0)
+ sourceFile.destPath = startingDestPath;
+ else
+ sourceFile.destPath = defaultStartingSourcePath;
+ }
+
+ if (sourceFile.destPath.Length > 0)
+ {
+ // if path is not absolute path
+ if (!Path.IsPathRooted(sourceFile.destPath))
+ {
+ if (startingDestPath.Length > 0)
+ {
+ string absPathFiltered = sourceFile.destPath;
+ // remove unwated characters at beginning of relative path
+ regExMatch = Regex.Match(sourceFile.destPath, @"^[\\\.]+(.+)", RegexOptions.IgnoreCase);
+ if (regExMatch.Success)
+ absPathFiltered = regExMatch.Groups[1].Value;
+
+ if (!PathManip.PathContainsAtLeastOneFolder(startingDestPath))
+ startingDestPath = PathManip.AddTrailingSlashToPath(startingDestPath);
+
+ sourceFile.destPath = Path.Combine(startingDestPath, absPathFiltered);
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"destdir\" cannot specify a relative path here since there's no absolute path defined in the parent node. XML node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Attribute \"destdir\" is missing or has no value in node " + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + " on line " + ((IXmlLineInfo)nav).LineNumber.ToString();
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+
+ sourceFile.masterOverwrite = nav.GetAttribute("overwriteallfiles", string.Empty).TrimEnd('\\');
+ sourceFile.Recursive = nav.GetAttribute("recursive", string.Empty).TrimEnd('\\');
+
+ if (!ProcessXML4thLevelNodes(nav, sourceFile, copyType))
+ setupSuccessful = false;
+
+ // after processing a package, perform file transfer
+ if (setupSuccessful && sourceFiles.Count > 0)
+ {
+ setupSuccessful = processFilePackage();
+ }
+
+ } while (nav.MoveToNext());
+
+ return setupSuccessful;
+ }
+
+ ///===================================================================================
+ /// ProcessXML4thLevelNodes
+ ///===================================================================================
+ ///
+ /// Process the child nodes of the 4th level node
+ /// in the XML file. Get all the files to be built
+ ///
+ /// navigator object for traversing XML tree
+ ///
+ /// true if processing node successfully, otherwise false
+ ///===================================================================================
+ private bool ProcessXML4thLevelNodes(XPathNavigator nav, SourceFile sourceFile, eCopyType copyType)
+ {
+ List fileActions = new List();
+ List filesSaveAs = new List();
+ List listOverwriteFiles = new List();
+ string fileInclude = "", fileExclude = "";
+ string[,] fileAction = new string[1, 2];
+ string[,] fileSaveAs = new string[1, 2];
+ string[,] overwriteFiles = new string[1, 2];
+ string msg = "", tempMsg = "";
+ bool setupSuccessful = true;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ string indentation = String.Empty;
+
+ if (nav.MoveToFirstChild())
+ {
+ // extract all the files and actions for files
+ do
+ {
+ fileAction[0, 0] = "";
+ fileAction[0, 1] = "";
+
+ fileSaveAs[0, 0] = "";
+ fileSaveAs[0, 1] = "";
+
+ overwriteFiles[0, 0] = "";
+ overwriteFiles[0, 1] = "";
+
+ if (string.Equals(nav.Name, "fileinclude", StringComparison.CurrentCultureIgnoreCase))
+ {
+ if (nav.Value.Length > 0)
+ {
+ if (fileInclude == string.Empty)
+ fileInclude = nav.Value.Trim();
+ else if (nav.Value.Trim() == "*.*")
+ fileInclude = nav.Value.Trim();
+ else if (fileInclude != "*.*")
+ fileInclude += "," + nav.Value.Trim();
+
+ // check to see if this file needs to be renamed at the destination
+ overwriteFiles[0, 0] = nav.GetAttribute("overwritefile", string.Empty);
+
+ if (overwriteFiles[0, 0].Length > 0)
+ {
+ // this is the file
+ overwriteFiles[0, 1] = nav.Value;
+ }
+
+ if (overwriteFiles[0, 0] != string.Empty && overwriteFiles[0, 1] != string.Empty)
+ {
+ listOverwriteFiles.Add(new string[,] { { overwriteFiles[0, 0], overwriteFiles[0, 1] } });
+ }
+
+ if (fileInclude != "*.*")
+ {
+ // check to see if this file needs to be renamed at the destination
+ fileSaveAs[0, 0] = nav.GetAttribute("saveas", string.Empty);
+
+ if (fileSaveAs[0, 0].Length > 0)
+ {
+ // this is the file
+ fileSaveAs[0, 1] = nav.Value;
+ }
+ }
+
+ if (fileSaveAs[0, 0] != string.Empty && fileSaveAs[0, 1] != string.Empty && sourceFile.SourcePath.Length > 0)
+ filesSaveAs.Add(new string[,] { { fileSaveAs[0, 0], fileSaveAs[0, 1] } });
+
+ // as long as the file specified doesn't contain wildcard
+ if (!Regex.IsMatch(nav.Value, @"\*", RegexOptions.IgnoreCase))
+ {
+ // check if there are any actions specified for this file
+ string attr = nav.GetAttribute("actions", string.Empty);
+
+ if (attr.Length > 0)
+ {
+ string[] actions = attr.Split(',');
+
+ if (actions.Length > 0)
+ {
+ foreach (string action in actions)
+ fileActions.Add(new string[,] { { action, nav.Value } });
+ }
+ }
+ }
+ }
+ }
+ else if (string.Equals(nav.Name, "fileexclude", StringComparison.CurrentCultureIgnoreCase))
+ {
+ if (nav.Value.Length > 0)
+ {
+ if (fileExclude == string.Empty)
+ fileExclude += nav.Value;
+ else
+ fileExclude += "," + nav.Value;
+ }
+ }
+ } while (nav.MoveToNext());
+
+ nav.MoveToParent();
+ }
+
+ Match regExMatch;
+
+ string[] filesToExclude = new string[] { };
+
+ if (fileExclude.Length > 0)
+ {
+ List paths = new List();
+ string[] files = fileExclude.Split(',');
+ string[] files2;
+
+ foreach (string file in files)
+ {
+ regExMatch = Regex.Match(file, @"\*\.[^\*,]+");
+ if (regExMatch.Success)
+ {
+ foreach (var drive in DriveInfo.GetDrives()
+ .Where(d => d.DriveType == DriveType.CDRom))
+ {
+ if (Regex.IsMatch(sourceFile.SourcePath, @"^" + Regex.Escape(PathManip.RemoveTrailingSlashInPath(drive.Name)) + @".*", RegexOptions.IgnoreCase))
+ {
+ while (!drive.IsReady || !Directory.Exists(sourceFile.SourcePath))
+ {
+ Hardware.OpenCdDrive(drive.Name);
+
+ tempMsg = "Please insert a disc";
+
+ if (sourceFile.cdLabel.Length > 0)
+ tempMsg += " labeled \"" + sourceFile.cdLabel + "\"";
+
+ tempMsg += " into drive " + drive.Name + " that has the following path:\n" + sourceFile.SourcePath + "\n\n Click OK to proceed";
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.OKCANCEL, null,
+ tempMsg, "Info", -1);
+
+ if (String.Equals(msg, "cancel", StringComparison.OrdinalIgnoreCase))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Unable to locate path: " + sourceFile.SourcePath;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ if (copyType == eCopyType.FILES)
+ {
+ if (String.Equals(sourceFile.Recursive, "yes", StringComparison.OrdinalIgnoreCase) || String.Equals(sourceFile.Recursive, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ files2 = Directory.GetFiles(sourceFile.SourcePath, regExMatch.Value, SearchOption.AllDirectories);
+ }
+ else
+ files2 = Directory.GetFiles(sourceFile.SourcePath, regExMatch.Value, SearchOption.TopDirectoryOnly);
+ }
+ else
+ files2 = Directory.GetFiles(sourceFile.SourcePath, regExMatch.Value, SearchOption.AllDirectories);
+
+ paths.AddRange(files2.ToList());
+ }
+ }
+ else
+ {
+ paths.Add(sourceFile.SourcePath + @"\" + file);
+ }
+ }
+
+ filesToExclude = paths.ToArray();
+ }
+
+ string[] filesToInclude = new string[] { };
+
+ if (setupSuccessful)
+ {
+ // look for wildcard search for files
+ regExMatch = Regex.Match(fileInclude, @"^\*\.\*$");
+
+ // if file to be copied is defined as *.*, then we want to include all files in the source directory
+ if (regExMatch.Success && sourceFile.SourcePath.Length > 0)
+ {
+ foreach (var drive in DriveInfo.GetDrives()
+ .Where(d => d.DriveType == DriveType.CDRom))
+ {
+ if (Regex.IsMatch(sourceFile.SourcePath, @"^" + Regex.Escape(PathManip.RemoveTrailingSlashInPath(drive.Name)) + @".*", RegexOptions.IgnoreCase))
+ {
+ while (!drive.IsReady || !Directory.Exists(sourceFile.SourcePath))
+ {
+ Hardware.OpenCdDrive(drive.Name);
+
+ tempMsg = "Please insert a disc";
+
+ if (sourceFile.cdLabel.Length > 0)
+ tempMsg += " labeled \"" + sourceFile.cdLabel + "\"";
+
+ tempMsg += " into drive " + drive.Name + " that has the following path:\n" + sourceFile.SourcePath + "\n\n Click OK to proceed";
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.OKCANCEL, null,
+ tempMsg, "Info", -1);
+
+ if (String.Equals(msg, "cancel", StringComparison.OrdinalIgnoreCase))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Unable to locate path: " + sourceFile.SourcePath;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ if (copyType == eCopyType.FOLDERS)
+ {
+ filesToInclude = Directory.GetFiles(sourceFile.SourcePath, fileInclude, SearchOption.AllDirectories);
+ }
+ else
+ {
+ if (String.Equals(sourceFile.Recursive, "yes", StringComparison.OrdinalIgnoreCase) || String.Equals(sourceFile.Recursive, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ filesToInclude = Directory.GetFiles(sourceFile.SourcePath, fileInclude, SearchOption.AllDirectories);
+ }
+ else
+ filesToInclude = Directory.GetFiles(sourceFile.SourcePath, fileInclude, SearchOption.TopDirectoryOnly);
+
+ // save overwrite file flag
+ foreach (string[,] overwriteFlag in listOverwriteFiles)
+ {
+ // if there's an overwrite flag associated with this file
+ if (string.Equals(overwriteFlag[0, 1], fileInclude, StringComparison.CurrentCultureIgnoreCase))
+ {
+ sourceFile.masterOverwrite = overwriteFlag[0, 0];
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (fileInclude.Length > 0) // get the individual files specified in the XML file
+ {
+ List paths = new List();
+ string[] files = fileInclude.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ string[] files2;
+ foreach (string file in files)
+ {
+ regExMatch = Regex.Match(file, @"\*\.[^\*,]+");
+ if (regExMatch.Success)
+ {
+ foreach (var drive in DriveInfo.GetDrives()
+ .Where(d => d.DriveType == DriveType.CDRom))
+ {
+ if (Regex.IsMatch(sourceFile.SourcePath, @"^" + Regex.Escape(PathManip.RemoveTrailingSlashInPath(drive.Name)) + @".*", RegexOptions.IgnoreCase))
+ {
+ while (!drive.IsReady || !Directory.Exists(sourceFile.SourcePath))
+ {
+ Hardware.OpenCdDrive(drive.Name);
+
+ tempMsg = "Please insert a disc";
+
+ if (sourceFile.cdLabel.Length > 0)
+ tempMsg += " labeled \"" + sourceFile.cdLabel + "\"";
+
+ tempMsg += " into drive " + drive.Name + " that has the following path:\n" + sourceFile.SourcePath + "\n\n Click OK to proceed";
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.OKCANCEL, null,
+ tempMsg, "Info", -1);
+
+ if (String.Equals(msg, "cancel", StringComparison.OrdinalIgnoreCase))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Unable to locate path: " + sourceFile.SourcePath;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ if (String.Equals(sourceFile.Recursive, "yes", StringComparison.OrdinalIgnoreCase) || String.Equals(sourceFile.Recursive, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ files2 = Directory.GetFiles(sourceFile.SourcePath, regExMatch.Value, SearchOption.AllDirectories);
+ }
+ else
+ files2 = Directory.GetFiles(sourceFile.SourcePath, regExMatch.Value, SearchOption.TopDirectoryOnly);
+
+ if (files2.Length > 0)
+ {
+ string overwriteFlag = "";
+ // save overwrite file flag
+ foreach (string[,] overwriteFlag2 in listOverwriteFiles)
+ {
+ // if there's an overwrite flag associated with this file
+ if (string.Equals(overwriteFlag2[0, 1], file, StringComparison.CurrentCultureIgnoreCase))
+ {
+ overwriteFlag = overwriteFlag2[0, 0];
+ break;
+ }
+ }
+
+ if (overwriteFlag.Length > 0)
+ {
+ for (int i = 0; i < files2.Length; i++)
+ {
+ files2[i] += "," + overwriteFlag;
+ }
+ }
+ }
+
+ paths.AddRange(files2.ToList());
+ }
+ }
+ else
+ {
+ if (sourceFile.SourcePath.Length > 0)
+ paths.Add(sourceFile.SourcePath + @"\" + file);
+ else
+ paths.Add(file);
+ }
+ }
+
+ filesToInclude = paths.ToArray();
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ if (filesToInclude.Length == 0 && copyType == eCopyType.FOLDERS)
+ {
+ foreach (var drive in DriveInfo.GetDrives()
+ .Where(d => d.DriveType == DriveType.CDRom))
+ {
+ if (Regex.IsMatch(sourceFile.SourcePath, @"^" + Regex.Escape(PathManip.RemoveTrailingSlashInPath(drive.Name)) + @".*", RegexOptions.IgnoreCase))
+ {
+ while (!drive.IsReady || !Directory.Exists(sourceFile.SourcePath))
+ {
+ Hardware.OpenCdDrive(drive.Name);
+
+ tempMsg = "Please insert a disc";
+
+ if (sourceFile.cdLabel.Length > 0)
+ tempMsg += " labeled \"" + sourceFile.cdLabel + "\"";
+
+ tempMsg += " into drive " + drive.Name + " that has the following path:\n" + sourceFile.SourcePath + "\n\n Click OK to proceed";
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.OKCANCEL, null,
+ tempMsg, "Info", -1);
+
+ if (String.Equals(msg, "cancel", StringComparison.OrdinalIgnoreCase))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. Unable to locate path: " + sourceFile.SourcePath;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (setupSuccessful)
+ filesToInclude = Directory.GetFiles(sourceFile.SourcePath, "*.*", SearchOption.AllDirectories);
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ // remove files that are excluded from build
+ if (filesToExclude.Length > 0 && filesToInclude.Length > 0 && sourceFile.SourcePath.Length > 0)
+ {
+ List filesToIncludeList = filesToInclude.ToList();
+ List filesToExcludeList = filesToExclude.ToList();
+
+ foreach (string excludePath in filesToExcludeList)
+ {
+ string pathToRemove = "";
+ foreach (string includePath in filesToIncludeList)
+ {
+ if (Regex.IsMatch(includePath, Regex.Escape(excludePath) + @"(,.+)*", RegexOptions.IgnoreCase))
+ {
+ pathToRemove = includePath;
+ break;
+ }
+ }
+
+ if (pathToRemove.Length > 0)
+ {
+ filesToIncludeList.Remove(pathToRemove);
+ }
+ }
+
+ filesToInclude = filesToIncludeList.ToArray();
+ }
+ }
+
+ string baseSourceFolder = sourceFile.SourcePath;
+ string baseDestFolder = sourceFile.destPath;
+
+ if (setupSuccessful)
+ {
+ // for each file to be copied, determine if there's an action associated with it
+ // or that it needs to be renamed, etc
+ foreach (string file in filesToInclude)
+ {
+ string[] fileParts = file.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ sourceFile.FileName = Path.GetFileName(fileParts[0]);
+ sourceFile.FileNameSaveAs = "";
+ sourceFile.Actions = new List();
+ sourceFile.individualOverwrite = "";
+
+ if (sourceFile.masterOverwrite.Length > 0)
+ sourceFile.individualOverwrite = sourceFile.masterOverwrite;
+
+ if (fileParts.Length == 1)
+ {
+ // save overwrite file flag
+ foreach (string[,] overwriteFlag in listOverwriteFiles)
+ {
+ // if there's an overwrite flag associated with this file
+ if (string.Equals(overwriteFlag[0, 1], sourceFile.FileName, StringComparison.CurrentCultureIgnoreCase))
+ {
+ sourceFile.individualOverwrite = overwriteFlag[0, 0];
+ break;
+ }
+ }
+ }
+ else
+ {
+ sourceFile.individualOverwrite = fileParts[1];
+ }
+
+ // save all the actions needed to be perform for this file
+ foreach (string[,] action in fileActions)
+ {
+ // if there's an action associated with this file
+ if (string.Equals(action[0, 1], sourceFile.FileName, StringComparison.CurrentCultureIgnoreCase))
+ {
+ //if (string.Equals(action[0, 0], eFileAction.CreateSWBuildIDEntries.ToString(), StringComparison.CurrentCultureIgnoreCase))
+ // sourceFile.Actions.Add(eFileAction.CreateSWBuildIDEntries);
+ //else if (string.Equals(action[0, 0], eFileAction.BuildProjectUsingVS2010Compiler.ToString(), StringComparison.CurrentCultureIgnoreCase))
+ // sourceFile.Actions.Add(eFileAction.BuildProjectUsingVS2010Compiler);
+ //else if (string.Equals(action[0, 0], eFileAction.BuildProjectUsingVS2009Compiler.ToString(), StringComparison.CurrentCultureIgnoreCase))
+ // sourceFile.Actions.Add(eFileAction.BuildProjectUsingVS2009Compiler);
+ //else if (string.Equals(action[0, 0], eFileAction.BuildProjectInDebug.ToString(), StringComparison.CurrentCultureIgnoreCase))
+ // sourceFile.Actions.Add(eFileAction.BuildProjectInDebug);
+ //else if (string.Equals(action[0, 0], eFileAction.BuildProjectInRelease.ToString(), StringComparison.CurrentCultureIgnoreCase))
+ // sourceFile.Actions.Add(eFileAction.BuildProjectInRelease);
+ }
+ }
+
+ foreach (string[,] fileRename in filesSaveAs)
+ {
+ // if a source file is to be renamed at the destination
+ if (string.Equals(fileRename[0, 1], sourceFile.FileName, StringComparison.CurrentCultureIgnoreCase) && sourceFile.SourcePath.Length > 0)
+ {
+ sourceFile.FileNameSaveAs = fileRename[0, 0];
+ break;
+ }
+ else if (Regex.IsMatch(fileRename[0, 1], @"^\*\.\w+$", RegexOptions.IgnoreCase)) // if the file to be renamed has a wildcard in it
+ {
+ regExMatch = Regex.Match(fileRename[0, 1], @".+(\.\w+)$", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success && regExMatch.Groups.Count > 1)
+ {
+ string pattern = Regex.Escape(regExMatch.Groups[1].Value) + @"$";
+
+ if (Regex.IsMatch(sourceFile.FileName, pattern, RegexOptions.IgnoreCase))
+ {
+ sourceFile.FileNameSaveAs = fileRename[0, 0];
+ break;
+ }
+ }
+ }
+ }
+
+ string fileSourcePath = Path.GetDirectoryName(file);
+ string regexPattern = Regex.Escape(baseSourceFolder) + @"\\(.+)";
+ if (copyType == eCopyType.FOLDERS)
+ {
+ regExMatch = Regex.Match(fileSourcePath, regexPattern, RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ sourceFile.SourcePath = fileSourcePath;
+ sourceFile.destPath = baseDestFolder + @"\" + regExMatch.Groups[1].Value;
+ }
+ }
+ else
+ sourceFile.SourcePath = fileSourcePath;
+
+ sourceFiles.Add(sourceFile);
+ }
+ }
+
+ return setupSuccessful;
+ }
+
+ bool verifyFilePackagesInfo()
+ {
+ bool setupSuccessful = true;
+ ConfigFileManager.Ini_KeyValue iniVal = new ConfigFileManager.Ini_KeyValue("");
+ string indentation = String.Empty;
+ string msg;
+
+ List textPropList = new List();
+
+ for (int i = 0; i < fileTransferPackages.Count; i++)
+ {
+ if (fileTransferPackages[i].iniValue.Length == 0)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + fileTransferPackages[i].iniSectionName
+ + "\n" + indentation + "Key: " + fileTransferPackages[i].iniKeyName
+ + "\n" + indentation + "Value: " + fileTransferPackages[i].iniValue
+ + "\n" + indentation + "Error Description: The value is missing for the above section in the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ setupSuccessful = false;
+ break;
+ }
+ else
+ {
+ iniVal = fileTransferPackages[i];
+ iniVal.iniValue = Path.GetFullPath(fileTransferPackages[i].iniValue);
+
+ fileTransferPackages[i] = iniVal;
+
+ if (!File.Exists(iniVal.iniValue))
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + fileTransferPackages[i].iniSectionName
+ + "\n" + indentation + "Key: " + fileTransferPackages[i].iniKeyName
+ + "\n" + indentation + "Value: " + fileTransferPackages[i].iniValue
+ + "\n" + indentation + "Error Description: The value indicates an invalid path in the above section in the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ setupSuccessful = false;
+ break;
+ }
+ }
+ }
+
+ return setupSuccessful;
+ }
+
+ public struct SourceFile
+ {
+ public string FileName
+ {
+ get;
+ set;
+ }
+
+ public string FileNameSaveAs
+ {
+ get;
+ set;
+ }
+
+ // specify whether to include files recursively
+ public string Recursive
+ {
+ get;
+ set;
+ }
+
+ // specify that all files will be overwritten
+ public string masterOverwrite
+ {
+ get;
+ set;
+ }
+
+ // specify that a particular file will be overwritten
+ public string individualOverwrite
+ {
+ get;
+ set;
+ }
+
+ public string SourcePath
+ {
+ get;
+ set;
+ }
+
+ public string destPath
+ {
+ get;
+ set;
+ }
+
+ public string cdLabel
+ {
+ get;
+ set;
+ }
+
+ public string SoftwareProduct
+ {
+ get;
+ set;
+ }
+
+ public List Actions
+ {
+ get;
+ set;
+ }
+
+ public SourceFile(string str)
+ : this()
+ {
+ FileName = "";
+ FileNameSaveAs = "";
+ SourcePath = "";
+ destPath = "";
+ cdLabel = "";
+ SoftwareProduct = "";
+ Recursive = "";
+ masterOverwrite = "";
+ individualOverwrite = "";
+ }
+
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/FoldersManager.cs b/AllPurposeAutoSetup/FoldersManager.cs
new file mode 100644
index 0000000..54f2874
--- /dev/null
+++ b/AllPurposeAutoSetup/FoldersManager.cs
@@ -0,0 +1,501 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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 CommonLib.Windows.Forms;
+using CommonLib.Windows.Misc;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class FoldersManager
+ {
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+
+ public List> dirsToCreate = new List>();
+
+ // this dictionary stores path and its associated share names
+ // it would look like this:
+ // [ path1 ] -> List[sharenames accounts_to_share]
+ // [ path2 ] -> List[sharenames accounts_to_share]
+ public Dictionary, List>> pathAndShareNames = new Dictionary, List>>();
+
+ Form m_parentForm;
+
+ public FoldersManager(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ public bool shareFolders(string sectionName)
+ {
+ string indentation = String.Empty;
+ bool setupSuccessful = true;
+ string msg, errorMsg = "";
+ ConfigFileManager.Ini_KeyValue iniVal = new ConfigFileManager.Ini_KeyValue("");
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=Configuring network shares=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ pathAndShareNames.Clear();
+
+ ConfigFileManager.readOneToManyDictionary(ConfigFileManager.ms_configGeneralInfo.iniFile,
+ sectionName, @"(path\d+)$", @"(path\d+)[^\d].+$", pathAndShareNames);
+
+ setupSuccessful = verifyNetworkSharesInfo();
+
+ if (setupSuccessful)
+ {
+ if (pathAndShareNames.Count == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- SKIPPED. Nothing to share";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+
+ foreach (KeyValuePair, List>> entry in pathAndShareNames)
+ {
+ int autoShareNameKeyIndex = entry.Value.FindIndex(x => Regex.IsMatch(x.iniKeyName, @"auto-generated", RegexOptions.IgnoreCase));
+ int shareNameKeyIndex = entry.Value.FindIndex(x => Regex.IsMatch(x.iniKeyName, @"path\d+_additional.+", RegexOptions.IgnoreCase));
+ int allowedAccountKeyIndex = entry.Value.FindIndex(x => Regex.IsMatch(x.iniKeyName, @"path\d+_allowed.+", RegexOptions.IgnoreCase));
+
+ List accounts = new List();
+ List shareNames = new List();
+
+ if (allowedAccountKeyIndex >= 0)
+ {
+ accounts = new List(entry.Value[allowedAccountKeyIndex].iniValue.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));
+ }
+
+ if (accounts.Count == 0)
+ {
+ accounts.Add("Everyone");
+ }
+
+ if (shareNameKeyIndex >= 0)
+ {
+ shareNames = new List(entry.Value[shareNameKeyIndex].iniValue.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));
+ }
+ else if (autoShareNameKeyIndex >= 0)
+ {
+ shareNames = new List(entry.Value[autoShareNameKeyIndex].iniValue.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries));
+ }
+
+ foreach (string name in shareNames)
+ {
+ string nameFormatted = name.Trim();
+
+ if (nameFormatted.Length == 1)
+ nameFormatted = nameFormatted.ToUpper();
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Sharing " + entry.Key.iniValue + " as " + nameFormatted;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "sharing") + 1;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "as") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ if (Directory.Exists("\\\\" + Environment.MachineName + '\\' + nameFormatted))
+ {
+ msg += " - SKIPPED. Share name already exists";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SKIPPED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "as") + 1;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "- skipped.") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ else
+ {
+ setupSuccessful = NetworkSharing.EnableNetworkFolderSharing(entry.Key.iniValue, nameFormatted, "", ref errorMsg);
+
+ if (!setupSuccessful)
+ {
+ msg += " - FAILED. " + errorMsg;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "as") + 1;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "- failed.") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ else
+ {
+ msg += " - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "as") + 1;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "- success.") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ foreach (string account in accounts)
+ {
+ string accountFormatted = account.Trim();
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Giving account " + accountFormatted + " Full Permission to network share " + nameFormatted;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "giving account") + 2;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "full permission") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = NetworkSharing.addAccountToNetworkShare(entry.Key.iniValue, nameFormatted, accountFormatted, "", ref errorMsg);
+
+ if (!setupSuccessful)
+ {
+ msg += " - FAILED. " + errorMsg;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "network share") + 2;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "- failed.") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ else
+ {
+ msg += " - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "network share") + 2;
+ textProp.wordCount = StringManip.GetPhraseWordIndexInText(msg, "- success.") - textProp.wordIndex;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ if (!setupSuccessful)
+ break;
+ }
+
+ if (!setupSuccessful)
+ break;
+ }
+ }
+ }
+ return setupSuccessful;
+ }
+
+ bool verifyNetworkSharesInfo()
+ {
+ bool setupSuccessful = true;
+ ConfigFileManager.Ini_KeyValue iniVal = new ConfigFileManager.Ini_KeyValue("");
+ string indentation = String.Empty;
+ string msg, str;
+ string[] splitStrings;
+
+ Dictionary, List>> tempOneToManyDict = new Dictionary, List>>();
+ List textPropList = new List();
+
+ // for every folder to be shared, extract the folder name and use it as a share name
+ foreach (KeyValuePair, List>> entry in pathAndShareNames)
+ {
+ int shareNameKeyIndex = entry.Value.FindIndex(x => Regex.IsMatch(x.iniKeyName, @"path\d+_additional.+", RegexOptions.IgnoreCase));
+
+ str = PathManip.RemoveTrailingSlashInPath(entry.Key.iniValue);
+ splitStrings = str.Split(new string[] { "\\", "/", ":" }, StringSplitOptions.RemoveEmptyEntries);
+
+ // get the name of folder to be shared
+ if (splitStrings.Length > 0 && splitStrings[splitStrings.Length - 1].Length > 0)
+ {
+ if (!tempOneToManyDict.ContainsKey(entry.Key))
+ {
+ tempOneToManyDict[entry.Key] = new List>(pathAndShareNames[entry.Key]);
+ }
+
+ if (shareNameKeyIndex >= 0 && tempOneToManyDict[entry.Key][shareNameKeyIndex].iniValue.Length == 0)
+ {
+ tempOneToManyDict[entry.Key].RemoveAt(shareNameKeyIndex);
+ shareNameKeyIndex = -1;
+ }
+
+ if (shareNameKeyIndex < 0)
+ {
+ // get the folder name of the path and save it as default share name
+ iniVal.iniSectionName = "Auto-Generated";
+ iniVal.iniKeyName = "Auto-Generated-Share-Name";
+ iniVal.iniValue = splitStrings[splitStrings.Length - 1];
+
+ // add default share name to path
+ tempOneToManyDict[entry.Key].Add(iniVal);
+ }
+ else
+ {
+ iniVal = tempOneToManyDict[entry.Key][shareNameKeyIndex];
+ iniVal.iniValue += ", " + splitStrings[splitStrings.Length - 1];
+ tempOneToManyDict[entry.Key][shareNameKeyIndex] = iniVal;
+ }
+ }
+ else
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + entry.Key.iniSectionName
+ + "\n" + indentation + "Key: " + entry.Key.iniKeyName
+ + "\n" + indentation + "Value: " + entry.Key.iniValue
+ + "\n" + indentation + "Error Description: The value above is invalid the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ }
+
+ pathAndShareNames = new Dictionary, List>>(tempOneToManyDict);
+
+ if (setupSuccessful)
+ pathAndShareNames = new Dictionary, List>>(tempOneToManyDict);
+
+ return setupSuccessful;
+ }
+
+ public bool createDirectories(string sectionName)
+ {
+ bool setupSuccessful = true;
+
+ DirectoryInfo di;
+ string msg, indentation;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+
+ textPropList.Add(textProp);
+ msg = "\n\n-=Creating Directories=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ dirsToCreate.Clear();
+
+ ConfigFileManager.parseConfigInfo(sectionName, dirsToCreate);
+
+ if (setupSuccessful)
+ {
+ if (dirsToCreate.Count == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- SKIPPED. Nothing create";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+
+ foreach (ConfigFileManager.Ini_KeyValue dir in dirsToCreate)
+ {
+ di = new DirectoryInfo(Path.GetFullPath(dir.iniValue));
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + di.ToString();
+ // Create the directory only if it does not already exist.
+ if (di.Exists == false)
+ {
+ try
+ {
+ di.Create();
+
+ msg += " - SUCCESS";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS"); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ catch (Exception e)
+ {
+ msg += " - FAILED. (" + e.Message + ")";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+ }
+ else
+ {
+ msg += " - SKIPPED. ( Directory already exists )";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SKIPPED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ if (!setupSuccessful)
+ break;
+ }
+ }
+ return setupSuccessful;
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/GutsConfigFileManager.cs b/AllPurposeAutoSetup/GutsConfigFileManager.cs
new file mode 100644
index 0000000..7ae1ccc
--- /dev/null
+++ b/AllPurposeAutoSetup/GutsConfigFileManager.cs
@@ -0,0 +1,448 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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 CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class GutsConfigFileManager
+ {
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+
+ // dictionary that stores key value pair for each entry in the GUTS config file
+ public List> gutsConfigEntries = new List>();
+
+ public ConfigFileManager.Ini_KeyValue sm3seekerConfigFile = new ConfigFileManager.Ini_KeyValue("");
+ public ConfigFileManager.Ini_KeyValue gutsBinariesLocation = new ConfigFileManager.Ini_KeyValue("");
+
+ Form m_parentForm;
+
+ public GutsConfigFileManager(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ public bool processGutsConfigFile(string sectionName)
+ {
+ bool setupSuccessful = true;
+ string msg, errMsg = String.Empty, sourceFile, destFile = "";
+ string indentation = String.Empty;
+ bool performFileCopying = true;
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=Processing GUTS Config File=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ gutsConfigEntries.Clear();
+
+ ConfigFileManager.parseConfigInfo(sectionName, gutsConfigEntries);
+
+ readGutsInfo();
+
+ setupSuccessful = verifyConfigInfo();
+
+ if (setupSuccessful)
+ {
+
+ destFile = PathManip.RemoveTrailingSlashInPath(gutsBinariesLocation.iniValue) + "\\Sm3Seeker.cfg";
+
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(233, 31, 195);
+ textProp.wordIndex = 1;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Copying " + Path.GetFileName(sm3seekerConfigFile.iniValue);
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ performFileCopying = true;
+
+ sourceFile = sm3seekerConfigFile.iniValue;
+ sourceFile = PathManip.GetProperFilePathCapitalization(sourceFile);
+
+ if (!File.Exists(sourceFile))
+ {
+ msg = " - FAILED. File " + sourceFile + " not found";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ }
+
+ if (File.Exists(destFile) && setupSuccessful)
+ {
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.YESNO, null, "File " + destFile + " already exists.\n\n Would you like to overwrite it?", "Info", -1);
+
+ if (String.Equals(msg, "no", StringComparison.OrdinalIgnoreCase))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.USER_SKIP);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- SKIPPED by user.";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ performFileCopying = false;
+ }
+ }
+
+ if (setupSuccessful && performFileCopying)
+ {
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- From: " + sourceFile;
+ msg += "\n" + indentation + "- To: " + destFile;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "From:");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "To:");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = FileManip.CopyFile(Path.GetDirectoryName(sourceFile), sourceFile, Path.GetDirectoryName(destFile), destFile, true, FileAttributes.Normal, ref errMsg);
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- SUCCESS.";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set file to read-write access
+ if (FileManip.SetFileAttributeToReadAndWrite(destFile, ref errMsg))
+ {
+ if (gutsConfigEntries.Count > 0)
+ {
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Color.FromArgb(233, 31, 195);
+ textProp.wordIndex = 2;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Modifying file " + destFile;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ string delimiter = "[,]";
+
+ // first we have to determine the correct keys based on the generic key provided in the INI file
+ // and add these dynamic keys to the existing dictionary of all the correct keys
+ foreach (ConfigFileManager.Ini_KeyValue configEntry in gutsConfigEntries)
+ {
+ List triplet = new List(configEntry.iniValue.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries));
+
+ if (triplet.Count > 0)
+ triplet[0] = triplet[0].Trim();
+
+ if (triplet.Count > 1)
+ triplet[1] = triplet[1].Trim();
+
+ if (triplet.Count > 2)
+ triplet[2] = triplet[2].Trim();
+
+ // section, key and value exist
+ if (triplet.Count == 3 && triplet[0].Length > 0 && triplet[1].Length > 0 && triplet[2].Length > 0)
+ {
+ setupSuccessful = modifyGutsConfigFile(destFile, triplet[0], triplet[1], triplet[2]);
+
+ if (!setupSuccessful)
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. " + errMsg;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ }
+ }
+ return setupSuccessful;
+ }
+
+ public bool modifyGutsConfigFile(string configFile, string configSectionName, string configKey, string configValue)
+ {
+ bool setupSuccessful = true;
+ string msg, errMsg = String.Empty;
+
+ string indentation = String.Empty;
+ Dictionary gutsSourceFileToDestFile = new Dictionary();
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ string pattern = @"(section +" + configSectionName + @"(?:(?!\nsection).)*\n" + configKey + @" +)[^;\r\n]+";
+ string replacement = "${1}" + configValue;
+
+ setupSuccessful = FileManip.ReplaceTextInFile(configFile, pattern, replacement, ref errMsg);
+
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "Setting " + configKey + "=" + configValue + " in section " + configSectionName;
+ if (setupSuccessful)
+ {
+ msg += " - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ else
+ {
+ msg += " - FAILED.";
+ if (errMsg.Length > 0)
+ msg += " " + errMsg;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ return setupSuccessful;
+
+ }
+
+ public void readGutsInfo()
+ {
+ string[] keyDataPair;
+ Dictionary keyAndValuePair = new Dictionary();
+
+ string sectionName;
+
+ string[] sectionData;
+
+ sectionName = ConfigFileManager.enum_INI_SECTION_NAMES.GUTS_Info.ToString();
+ sectionData = ConfigFileManager.ms_configGeneralInfo.iniFile.ReadSectionData(sectionName);
+
+ gutsBinariesLocation.iniKeyName = "Guts_Bin_Dir";
+ gutsBinariesLocation.iniSectionName = sectionName;
+
+ sm3seekerConfigFile.iniKeyName = "sm3seeker_config_file";
+ sm3seekerConfigFile.iniSectionName = sectionName;
+
+ foreach (string path in sectionData)
+ {
+ keyDataPair = path.Split('=');
+
+ if (String.Equals(keyDataPair[0], gutsBinariesLocation.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ if (keyDataPair.Length == 2)
+ {
+ gutsBinariesLocation.iniValue = keyDataPair[1];
+ }
+ }
+ else if (String.Equals(keyDataPair[0], sm3seekerConfigFile.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ if (keyDataPair.Length == 2 && keyDataPair[1].Length > 0)
+ {
+ sm3seekerConfigFile.iniValue = Path.GetFullPath(keyDataPair[1]);
+ }
+ }
+ }
+ }
+
+ bool verifyConfigInfo()
+ {
+ bool setupSuccessful = true;
+ string indentation = String.Empty;
+ string msg, tempPath;
+
+ List textPropList = new List();
+
+ if (gutsBinariesLocation.iniValue.Length == 0)
+ {
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + gutsBinariesLocation.iniSectionName
+ + "\n" + indentation + "Key: " + gutsBinariesLocation.iniKeyName
+ + "\n" + indentation + "Value: " + gutsBinariesLocation.iniValue
+ + "\n" + indentation + "Error Description: Either one or a combination of Section, Key, or Value is not defined in the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ else if (sm3seekerConfigFile.iniValue.Length == 0)
+ {
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + sm3seekerConfigFile.iniSectionName
+ + "\n" + indentation + "Key: " + sm3seekerConfigFile.iniKeyName
+ + "\n" + indentation + "Value: " + sm3seekerConfigFile.iniValue
+ + "\n" + indentation + "Error Description: Either one or a combination of Section, Key, or Value is not defined in the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+
+ if (setupSuccessful)
+ {
+ tempPath = Path.GetFullPath(gutsBinariesLocation.iniValue);
+
+ if (!Directory.Exists(gutsBinariesLocation.iniValue))
+ {
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + gutsBinariesLocation.iniSectionName
+ + "\n" + indentation + "Key: " + gutsBinariesLocation.iniKeyName
+ + "\n" + indentation + "Value: " + gutsBinariesLocation.iniValue
+ + "\n" + indentation + "Error Description: The path defined in the value above is invalid. Translated path " + tempPath;
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ else
+ gutsBinariesLocation.iniValue = tempPath;
+ }
+
+ if (setupSuccessful)
+ {
+ tempPath = Path.GetFullPath(sm3seekerConfigFile.iniValue); ;
+
+ if (!File.Exists(sm3seekerConfigFile.iniValue))
+ {
+ indentation = Common.getIndentation(2);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + sm3seekerConfigFile.iniSectionName
+ + "\n" + indentation + "Key: " + sm3seekerConfigFile.iniKeyName
+ + "\n" + indentation + "Value: " + sm3seekerConfigFile.iniValue
+ + "\n" + indentation + "Error Description: The path defined in the value above is invalid. Translated path " + tempPath;
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ else
+ sm3seekerConfigFile.iniValue = tempPath;
+ }
+
+ return setupSuccessful;
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/GutsSoftwareBuildAssistant.cs b/AllPurposeAutoSetup/GutsSoftwareBuildAssistant.cs
new file mode 100644
index 0000000..e6390d0
--- /dev/null
+++ b/AllPurposeAutoSetup/GutsSoftwareBuildAssistant.cs
@@ -0,0 +1,698 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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 CommonLib.Windows.Forms;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class GutsSoftwareBuildAssistant
+ {
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+ public event Action RestartApplication;
+
+ public List> gutsPrebuildParams = new List>();
+
+ Form m_parentForm;
+
+ public GutsSoftwareBuildAssistant(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ // if one were to build GUTS from the files pulled from Synergy, the build will fail because
+ // additional files (source and headers) must be added to the GUTS project in order to build
+ // GUTS successfully. There's a perl script (dashboard.pl) that creates all the necessary files.
+ // But before the dashboard.pl can create all additional files, that path to the GUTS project
+ // must be specified in the windows environmental system variables and that the path to the Perl
+ // executable must be in the system Path variable. If these 2 things are not correct, the dashboard.pl
+ // will not be able to copy files to the GUTS project folder and GUTS will fail the build
+ // this function will ensure that everything is right to run the dashboard.pl and that it can create
+ // files and add them to the GUTS project folders.
+ public bool gutsPrebuildCheck(string sectionName)
+ {
+ string msg, indentation = String.Empty, gutsRootPath = "";
+ bool setupSuccessful = true;
+ ConfigFileManager.Ini_KeyValue gutsDevelopmentFolder = new ConfigFileManager.Ini_KeyValue("");
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 10;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=GUTS Pre-build Check=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ gutsPrebuildParams.Clear();
+
+ ConfigFileManager.parseConfigInfo(sectionName, gutsPrebuildParams);
+
+ if (setupSuccessful)
+ {
+ setupSuccessful = verifyGutsDirectoryStructure(ref gutsRootPath);
+
+ if (setupSuccessful)
+ setupSuccessful = runGutsPrebuildScript(gutsRootPath);
+ }
+
+ return setupSuccessful;
+ }
+
+ bool verifyGutsDirectoryStructure(ref string gutsRootPath)
+ {
+ bool setupSuccessful = true;
+ string msg, indentation = String.Empty;
+ Match regExMatch;
+ ConfigFileManager.Ini_KeyValue gutsDevelopmentFolder = new ConfigFileManager.Ini_KeyValue("");
+ List paths = new List();
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ gutsRootPath = "";
+
+ gutsDevelopmentFolder = getGutsDevelopmentFolderIniInfo();
+ if (gutsDevelopmentFolder.iniValue.Length == 0)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + gutsDevelopmentFolder.iniSectionName
+ + "\n" + indentation + "Key: " + gutsDevelopmentFolder.iniKeyName
+ + "\n" + indentation + "Value: " + gutsDevelopmentFolder.iniValue
+ + "\n" + indentation + "Error Description: The key or value is missing for the above section in the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+
+ if (setupSuccessful)
+ {
+ regExMatch = Regex.Match(gutsDevelopmentFolder.iniValue, @"(.+\\GUTS[^\\]*)\\?.*", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ gutsRootPath = regExMatch.Groups[1].Value;
+ }
+ else
+ gutsRootPath = PathManip.RemoveTrailingSlashInPath(gutsDevelopmentFolder.iniValue) + "\\" + "GUTS";
+
+ paths.Add(gutsRootPath);
+ paths.Add(gutsRootPath + "\\SM3_Tools\\Dashboard");
+ paths.Add(gutsRootPath + "\\SM3\\src\\app");
+
+ foreach (string path in paths)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Verify path \"" + PathManip.GetProperDirectoryCapitalization(path) + "\"";
+
+ if (Directory.Exists(path))
+ {
+ msg += " - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ else
+ {
+ msg += " - FAILED.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ if (!setupSuccessful)
+ break;
+ }
+ }
+
+ return setupSuccessful;
+ }
+
+ bool runGutsPrebuildScript(string gutsRootPath)
+ {
+ bool environmentVarChanged = false;
+ string msg = "", additionalFileMissing = "", errMsg = "", indentation, dashboardScriptPath, currentPathEnvVar = "", currentSm3SeekerEnvVar = "";
+ bool setupSuccessful = true;
+ ConfigFileManager.Ini_KeyValue genericIniInfo = new ConfigFileManager.Ini_KeyValue("");
+ ConfigFileManager.Ini_KeyValue pathAndNameOfAddtionalFilesList = new ConfigFileManager.Ini_KeyValue("");
+ ConfigFileManager.Ini_KeyValue perlBinaryPath = new ConfigFileManager.Ini_KeyValue("");
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+
+ pathAndNameOfAddtionalFilesList = getPathAndNameOfAddtionalFileList();
+ genericIniInfo = pathAndNameOfAddtionalFilesList;
+
+ perlBinaryPath = getPerlBinaryPathIniInfo();
+ if (genericIniInfo.iniValue.Length > 0)
+ genericIniInfo = perlBinaryPath;
+
+ if (genericIniInfo.iniValue.Length == 0)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. "
+ + "\n" + indentation + "File: " + ConfigFileManager.ms_configGeneralInfo.pathAndNameOfConfigFile
+ + "\n" + indentation + "Section: " + genericIniInfo.iniSectionName
+ + "\n" + indentation + "Key: " + genericIniInfo.iniKeyName
+ + "\n" + indentation + "Value: " + genericIniInfo.iniValue
+ + "\n" + indentation + "Error Description: The key or value is missing for the above section in the INI file.";
+
+ Common.formatConfigIniFailureMessage(msg, textPropList);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+
+ if (setupSuccessful)
+ {
+ if (File.Exists(pathAndNameOfAddtionalFilesList.iniValue))
+ {
+ verifyAdditionalFilesAlreadyExistInGutsProject(gutsRootPath, pathAndNameOfAddtionalFilesList.iniValue, ref additionalFileMissing, ref errMsg);
+
+ if (errMsg.Length > 0)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Parsing file \"" + pathAndNameOfAddtionalFilesList.iniValue + "\" - FAILED. " + errMsg;
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+ else if (additionalFileMissing.Length > 0)
+ {
+ ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.INFO, null, "File \"" + additionalFileMissing + "\" is missing. \n\nProceeding with running pre-build script to create necessary files." , "Info", -1);
+ }
+ else
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Verify additional files already exist within \"" + gutsRootPath + "\" - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ }
+ else
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Verify file \"" + pathAndNameOfAddtionalFilesList.iniValue + "\" - FAILED.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+
+ if ( msg.Length > 0 )
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+
+ // at least 1 required file is missing from the GUTS project folder, we must run script to copy all the necessary files to GUTS folder
+ if (setupSuccessful && additionalFileMissing.Length > 0)
+ {
+ dashboardScriptPath = gutsRootPath + @"\SM3_Tools\Dashboard\dashboard.pl";
+
+ if (!File.Exists(dashboardScriptPath))
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Verify file \"" + dashboardScriptPath + "\" - FAILED. File does not exist";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+
+ string perlAppPath = PathManip.AddTrailingSlashToPath(perlBinaryPath.iniValue) + "Perl.exe";
+ if (!File.Exists(perlAppPath))
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Verify file \"" + perlAppPath + "\" - FAILED. File does not exist. Please install Perl.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED.");
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+
+ if (setupSuccessful)
+ {
+ try
+ {
+ currentPathEnvVar = System.Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
+
+ perlBinaryPath.iniValue = PathManip.RemoveTrailingSlashInPath(perlBinaryPath.iniValue);
+ }
+ catch (Exception e)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Querying system environment variable \"Path\" - FAILED. (" + e.Message + ")";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ try
+ {
+ currentSm3SeekerEnvVar = System.Environment.GetEnvironmentVariable("SM3_SEEKER", EnvironmentVariableTarget.Machine);
+ }
+ catch (Exception e)
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Querying system environment variable \"SM3_SEEKER\" - FAILED. (" + e.Message + ")";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ setupSuccessful = false;
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ // if the perl binary path is not specified in the system environment variable "Path", we add it
+ if (!Regex.IsMatch(currentPathEnvVar, @".*" + Regex.Escape(perlBinaryPath.iniValue) + @".*", RegexOptions.IgnoreCase))
+ {
+ currentPathEnvVar += ";" + perlBinaryPath.iniValue;
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting environment variable [Path=$Path;" + perlBinaryPath.iniValue + "]";
+ try
+ {
+ System.Environment.SetEnvironmentVariable("Path", currentPathEnvVar, EnvironmentVariableTarget.Machine);
+
+ environmentVarChanged = true;
+
+ msg += " - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ catch (Exception e)
+ {
+ msg += " - FAILED. (" + e.Message + ")";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ }
+ }
+
+ if (setupSuccessful)
+ {
+ // if the SM3_SEEKR path does not match the GUTS Development Folder path, we change it
+ if (!Regex.IsMatch(currentSm3SeekerEnvVar, @"^" + Regex.Escape(gutsRootPath) + @"\\SM3$", RegexOptions.IgnoreCase))
+ {
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting environment variable [SM3_SEEKER=" + gutsRootPath + @"\SM3]";
+ try
+ {
+ System.Environment.SetEnvironmentVariable("SM3_SEEKER", gutsRootPath + @"\SM3", EnvironmentVariableTarget.Machine);
+
+ environmentVarChanged = true;
+
+ msg += " - SUCCESS.";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "SUCCESS."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+ }
+ catch (Exception e)
+ {
+ msg += " - FAILED. (" + e.Message + ")";
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = StringManip.GetPhraseWordIndexInText(msg, "FAILED."); ;
+ textProp.wordCount = 1;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ setupSuccessful = false;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+ }
+
+ if (environmentVarChanged)
+ {
+ ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.INFO, null, "The application has made changes/additions to the System Environment Variables.\n\n The application must be restarted for the System Environment Variables to take effect.\n\n Click OK to close the application and run the application again.", "Info", -1);
+
+ // raise the event to restart the application
+ RestartApplication();
+ }
+
+ if (setupSuccessful && !((frmSetupStatusDisplay)m_parentForm).applicationNeedsToBeRestarted())
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = defaultTextProp.textColor;
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Regular);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Executing script to create required files to GUTS project folder";
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ msg = ((frmSetupStatusDisplay)m_parentForm).displayMessageBox(MessageBoxCustom.PopUpMsgType.YESNO, null, "Would you like to run the perl script to copy necessary files to GUTS folder?", "Info", -1);
+
+ if (String.Equals(msg, "yes", StringComparison.OrdinalIgnoreCase))
+ {
+ try
+ {
+ var process = Process.Start(perlAppPath, dashboardScriptPath);
+ process.WaitForExit();
+
+ verifyAdditionalFilesAlreadyExistInGutsProject(gutsRootPath, pathAndNameOfAddtionalFilesList.iniValue, ref additionalFileMissing, ref errMsg);
+
+ if (errMsg.Length == 0 && additionalFileMissing.Length == 0)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = " - SUCCESS";
+
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ if (errMsg.Length > 0 )
+ msg = " - FAILED. " + errMsg;
+ else
+ msg = " - FAILED. " + additionalFileMissing + " not found.";
+
+ setupSuccessful = false;
+ }
+ }
+ catch (Exception e)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = " - FAILED. Error executing file " + dashboardScriptPath + ". " + e.Message;
+
+ setupSuccessful = false;
+ }
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = " - FAILED. User chooses to not run script.";
+
+ setupSuccessful = false;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+ }
+
+ return setupSuccessful;
+ }
+
+ void verifyAdditionalFilesAlreadyExistInGutsProject(string gutsRootPath, string pathAndNameToListOfFiles, ref string fileMissing, ref string errMsg)
+ {
+ string line, filePart2, filePath;
+ Match regExMatch;
+ errMsg = "";
+ fileMissing = "";
+ FileStream fs = null;
+ StreamReader reader = null;
+
+ try
+ {
+ fs = new FileStream(pathAndNameToListOfFiles, FileMode.Open, FileAccess.Read);
+ reader = new StreamReader(fs, Encoding.Default);
+
+ while ((line = reader.ReadLine()) != null)
+ {
+ line = line.Trim();
+
+ if (line.Length > 0)
+ {
+ regExMatch = Regex.Match(line, @"(.*\\)?(SM3\\.+)", RegexOptions.IgnoreCase);
+
+ if (regExMatch.Success)
+ {
+ filePart2 = regExMatch.Groups[2].Value;
+
+ filePath = gutsRootPath + "\\" + filePart2;
+
+ if (!File.Exists(filePath))
+ {
+ fileMissing = filePath;
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ errMsg = ex.Message;
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.Close();
+ fs.Close();
+ }
+ }
+
+ }
+
+ ConfigFileManager.Ini_KeyValue getPerlBinaryPathIniInfo()
+ {
+ ConfigFileManager.Ini_KeyValue iniInfo = new ConfigFileManager.Ini_KeyValue("");
+ iniInfo.iniKeyName = "perl_binary_path";
+ iniInfo.iniSectionName = ConfigFileManager.enum_INI_SECTION_NAMES.GUTS_Pre_Build_Assistance.ToString();
+
+ foreach (ConfigFileManager.Ini_KeyValue iniParam in gutsPrebuildParams)
+ {
+ if (String.Equals(iniParam.iniKeyName, iniInfo.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ iniInfo = iniParam;
+ if (iniInfo.iniValue.Length > 0)
+ iniInfo.iniValue = Path.GetFullPath(iniInfo.iniValue);
+ break;
+ }
+ }
+
+ return iniInfo;
+ }
+
+ ConfigFileManager.Ini_KeyValue getGutsDevelopmentFolderIniInfo()
+ {
+ ConfigFileManager.Ini_KeyValue iniInfo = new ConfigFileManager.Ini_KeyValue("");
+ iniInfo.iniKeyName = "GUTS_Development_Folder";
+ iniInfo.iniSectionName = ConfigFileManager.enum_INI_SECTION_NAMES.GUTS_Pre_Build_Assistance.ToString();
+
+ foreach (ConfigFileManager.Ini_KeyValue iniParam in gutsPrebuildParams)
+ {
+ if (String.Equals(iniParam.iniKeyName, iniInfo.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ iniInfo = iniParam;
+ if (iniInfo.iniValue.Length > 0)
+ iniInfo.iniValue = Path.GetFullPath(iniInfo.iniValue);
+ break;
+ }
+ }
+
+ return iniInfo;
+ }
+
+ ConfigFileManager.Ini_KeyValue getPathAndNameOfAddtionalFileList()
+ {
+ ConfigFileManager.Ini_KeyValue iniInfo = new ConfigFileManager.Ini_KeyValue("");
+ iniInfo.iniKeyName = "list_of_additional_files";
+ iniInfo.iniSectionName = ConfigFileManager.enum_INI_SECTION_NAMES.GUTS_Pre_Build_Assistance.ToString();
+
+ foreach (ConfigFileManager.Ini_KeyValue iniParam in gutsPrebuildParams)
+ {
+ if (String.Equals(iniParam.iniKeyName, iniInfo.iniKeyName, StringComparison.OrdinalIgnoreCase))
+ {
+ iniInfo = iniParam;
+ if (iniInfo.iniValue.Length > 0)
+ iniInfo.iniValue = Path.GetFullPath(iniInfo.iniValue);
+ break;
+ }
+ }
+
+ return iniInfo;
+ }
+ }
+}
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_MK698.ini b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_MK698.ini
new file mode 100644
index 0000000..cc090c2
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_MK698.ini
@@ -0,0 +1,663 @@
+; ************************************************* AUTO SETUP CONFIGURATION FILE *****************************************************
+; Description:
+; This is an INI file which contains the configuration information for the automated setup of either an
+; ENGINEERING or PRODUCTION environment in a Windows OS.
+;
+; Author: Duc Le
+;
+; ******************************************************************************************************************************
+;
+;
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+[General]
+Program_Name = SM3
+; 64-bit or 32-bit. Possible values: 32 or 64
+Application_Platform = 32
+
+[Global_Settings]
+Always_Run_Application_Using_Admin_Account = true
+Suppress_All_Prompts = true
+Provide_Windows_Password_For_Auto_Login = true
+
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+; This section defines all the setup steps to be performed and allow the user the option of enabling/disabling each step
+; The key can be anything.
+; The value must define the setup step and its associated section name separated by comma: Setup_Step,Section_Name
+; Below is a list of all possible setup steps:
+; CONFIGURE_NETWORK_ADAPTERS
+; RUN_APPLICATIONS
+; INSTALL_SOFTWARE_PACKAGES
+; ENABLE_INTERNET_INFORMATION_SERVICES
+; CREATE_DIRECTORIES
+; CREATE_NETWORK_SHARES
+; SET_ENVIRONMENT_VARIABLES
+; SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS
+; TRANSFER_FILE_PACKAGES
+; MODIFY_WINDOWS_REGISTRY
+; PROCESS_GUTS_CONFIG_FILE
+; CREATE_WINDOWS_SHORTCUTS
+; ASSIST_BUILDING_GUTS_APP
+; REMOVE_FILES_FOLDERS
+;
+; The setup setup can be run more than once by creating another key and assigned the setup step to it
+; Each setup step needs a section name. Section name provides all the information necessary for the setup step
+; The sequence of the execution of the setup steps will be in the same order as they are specified.
+; ******************************************************************************************************************************
+[Setup_Step_Manager]
+step = RUN_APPLICATIONS,Extract_Visual_Studio_Archives
+step = TRANSFER_FILE_PACKAGES,DVD_Software_Suite
+step = RUN_APPLICATIONS,Extract_Software_Suite
+step = INSTALL_SOFTWARE_PACKAGES,Install_Microsoft_HotFix
+step = RUN_APPLICATIONS,Import_Trusted_Publisher_Certificates
+step = INSTALL_SOFTWARE_PACKAGES,Install_Software
+step = RUN_APPLICATIONS,Shut_Down_National_Instrument_Processes
+step = REMOVE_FILES_FOLDERS , Files_Folders_Removal
+
+;step = ENABLE_INTERNET_INFORMATION_SERVICES,Windows_Features
+;step = CREATE_DIRECTORIES,Paths_Creation
+;step = CREATE_NETWORK_SHARES,Paths_Sharing
+;step = SET_ENVIRONMENT_VARIABLES,Env_Variables
+;step = SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS
+;step = TRANSFER_FILE_PACKAGES,Files_Transfer_Packages
+;step = MODIFY_WINDOWS_REGISTRY,Windows_Registry
+;step = PROCESS_GUTS_CONFIG_FILE,GUTS_Config_File
+;step = CREATE_WINDOWS_SHORTCUTS,Windows_Shortcuts
+;step = ASSIST_BUILDING_GUTS_APP,GUTS_Pre_Build_Assistance
+;step = REMOVE_FILES_FOLDERS , Files_Folders_Removal
+
+[Install_Microsoft_HotFix]
+app1_name = HotFix for Windows (KB2921916)
+app1_setup_file = c:\windows\system32\wusa.exe
+app1_setup_argument = "{user_temp_folder}\mk698\extraction\MS_HotFix\Windows6.1-KB2921916-x64.msu" /quiet /norestart
+app1_reg_path = SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages\Package_2_for_KB2921916~31bf3856ad364e35~amd64~~6.1.1.0
+app1_reg_type = local_machine
+app1_reboot_computer_at_completion = yes
+app1_reboot_computer_immediately = yes
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to install various software application
+; For each software application to be installed, 4 things can be defined:
+;
+; Possible keys:
+; app#_name (REQUIRED. Name of the application to be installed/checked)
+; app#_setup_file (OPTIONAL. Path and name of the installer)
+; - the setup file can make use of macros. Look below for the available macros
+; app#_setup_argument (OPTIONAL. Argument for the setup file. Usually to perform unattended install)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; app#_setup_confirm_prompt (OPTIONAL. Prompt user to confirm before installation starts.)
+; - possible values: yes, no
+; - yes: there will be prompt asking user confirm/refuse install
+; - no: installation will start automatically ( this is the default )
+; app#_exe_file (REQUIRED only if app#_hklm_reg_key is not specified.
+; This is used to verify that the software successfully installed)
+; app#_reg_path (REQUIRED only if app#_exe_file is not specified. Registry folder path, not including valuename)
+; app#_reg_type (REQUIRED only if app#_reg_key is specified)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; app#_reg_value (REQUIRED only if app#_reg_key is specified. Registry value name's value)
+; app#_reg_name (REQUIRED only if app#_reg_key is specified. Registry value name)
+; app#_reg_compare (REQUIRED only if app#_reg_key is specified. Compare operator between value name's value specified here versus actual value read from registry)
+; - there are only six options for this key ( eq, lt, gt, lte, gte, ne )
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; example 1:
+; app1_name = Perl 5.6.1.638
+; app1_setup_file = {user_temp_folder}\Installer.bat
+; app1_exe_file = C:\Perl\bin\perl.exe
+;
+; example 2:
+; app1_reg_path = SOFTWARE\National Instruments\NI-488.2\CurrentVersion
+; app1_reg_type = local_machine
+; app1_reg_value = 15.0
+; app1_reg_name = Version
+; app1_reg_compare = gte
+; app1_name = National Instrument 488.2 (v15 or higher)
+; app1_setup_file = C:\ni\setup.exe
+;
+; example 3:
+; app1_exe_file = C:\Perl\bin\perl.exe
+; app1_name = Perl 5.6.1.638
+;
+; example 4:
+; app1_name = Sapera LT 8.11 (x64)
+; app1_setup_file = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\Software\TeledyneDalsa\Sapera_LT_8.11_RuntimeSetup.exe
+; app1_setup_argument = -s -f1"{app1_setup_file}\sapera_setup.iss"
+; app1_reg_path = SOFTWARE\Teledyne DALSA\Sapera LT
+; app1_reg_type = local_machine
+; app1_reg_name = IsSaperaFrameGrabberSupport
+;
+; ******************************************************************************************************************************
+; Visual Studio ClassRoot Registry Keys
+;
+; {"VS2005", "VisualStudio.DTE.8.0"},
+; {"VS2008", "VisualStudio.DTE.9.0"},
+; {"VS2010", "VisualStudio.DTE.10.0"},
+; {"VS2012", "VisualStudio.DTE.11.0"},
+; {"VS2013", "VisualStudio.DTE.12.0"},
+; {"VS2015", "VisualStudio.DTE.13.0"}
+;
+; Visual Studio Redistributable Local_Machine Registry Keys
+;
+; {"VS2005_x64", @"SOFTWARE\Classes\Installer\Products\1af2a8da7e60d0b429d7e6453b3d0182"},
+; {"VS2005_x86", @"SOFTWARE\Classes\Installer\Products\c1c4f01781cc94c4c8fb1542c0981a2a"},
+; {"VS2008_x64", @"SOFTWARE\Classes\Installer\Products\67D6ECF5CD5FBA732B8B22BAC8DE1B4D"},
+; {"VS2008_x86", @"SOFTWARE\Classes\Installer\Products\6E815EB96CCE9A53884E7857C57002F0"},
+; {"VS2010_x64", @"SOFTWARE\Classes\Installer\Products\1926E8D15D0BCE53481466615F760A7F"},
+; {"VS2010_x86", @"SOFTWARE\Classes\Installer\Products\1D5E3C0FEDA1E123187686FED06E995A"},
+; {"VS2012_x64", @"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}"},
+; {"VS2012_x86", @"SOFTWARE\Classes\Installer\Dependencies\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f}"},
+; {"VS2013_x64", @"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}"},
+; {"VS2013_x86", @"SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}"},
+; {"VS2015_x64", @"SOFTWARE\Classes\Installer\Dependencies\{3ee5e5bb-b7cc-4556-8861-a00a82977d6c}"},
+; {"VS2015_x86", @"SOFTWARE\Classes\Installer\Dependencies\{23daf363-3020-4059-b3ae-dc4ad39fed19}"}
+;
+; ******************************************************************************************************************************
+[Install_Software]
+app1_name = Visual Studio 2012
+app1_setup_argument = /passive /norestart
+app1_reg_path = VisualStudio.DTE.11.0
+app1_reg_type = classes_root
+app1_setup_file = {user_temp_folder}\mk698\extraction\vs2012\vs_professional.exe
+
+app2_name = Visual Studio 2012 - Update 4
+app2_setup_file = {user_temp_folder}\mk698\extraction\vs2012_update4\VS2012.4.exe
+app2_setup_argument = /passive /norestart
+app2_reg_path = SOFTWARE\Wow6432Node\Microsoft\DevDiv\vc\Servicing\11.0\CompilerCore\1033
+app2_reg_type = local_machine
+app2_reg_value = 11.0.61030
+app2_reg_name = UpdateVersion
+app2_reg_compare = eq
+
+app3_name = SSI Test Executive 6.42.1 (v1.0.0)
+app3_setup_file = c:\windows\system32\msiexec.exe
+app3_setup_argument = /i "{user_temp_folder}\mk698\extraction\SSI_Test_Exec_v6_42_1\win32\SSI Test Executive 6.42.1.msi" /passive /norestart ALLUSERS{equal_sign}1
+app3_reg_display_name = SSI Test Executive 6.42.1
+app3_reg_type = local_machine
+app3_reg_value = 1.0.0
+app3_reg_name = DisplayVersion
+app3_reg_compare = eq
+
+app4_name = ActivePerl 5.8.8 Build 817
+app4_setup_file = c:\windows\system32\msiexec.exe
+app4_setup_argument = /i "{user_temp_folder}\mk698\extraction\ActivePerl_v5_8_8\ActivePerl-5.8.8.817-MSWin32-x86-257965.msi" /passive /norestart
+app4_reg_display_name = ActivePerl 5.8.8 Build 817
+app4_reg_type = local_machine
+app4_reg_value = 5.8.817
+app4_reg_name = DisplayVersion
+app4_reg_compare = eq
+
+app5_name = Windows Software Development Kit for Windows 8.1
+app5_setup_file = {user_temp_folder}\mk698\extraction\WinSDK_v8_1\sdksetup.exe
+app5_setup_argument = /quiet /norestart
+app5_reg_display_name = Windows Software Development Kit
+app5_reg_type = local_machine
+app5_reg_value = 8.100.26936
+app5_reg_name = DisplayVersion
+app5_reg_compare = eq
+app5_reboot_computer_at_completion = yes
+
+; needed for National Instrument Drivers
+app6_name = Microsoft .NET Framework 4.6.2
+app6_setup_file = {user_temp_folder}\mk698\extraction\DotNet_Framework_4_6_2\NDP462-KB3151800-x86-x64-AllOS-ENU.exe
+app6_setup_argument = /passive /norestart
+app6_reg_display_name = Microsoft .NET Framework 4.6.2
+app6_reg_type = local_machine
+app6_reg_value = 4.6
+app6_reg_name = DisplayVersion
+app6_reg_compare = gte
+
+; app61_name = NI LabWindows/CVI Runtime (v. 17)
+; app61_setup_file = {user_temp_folder}\mk698\extraction\NI_LabWindows_CVI_Runtime_v17\setup.exe
+; app61_setup_argument = /qb /r:n /AcceptLicenses yes
+; app61_reg_display_name = NI LabWindows/CVI SxS Runtime 2017
+; app61_reg_type = local_machine
+; app61_reg_value = 17
+; app61_reg_name = DisplayVersion
+; app61_reg_compare = gte
+; app61_setup_reboot_computer = yes
+
+app62_name = NI LabWindows/CVI (v. 17)
+app62_setup_file = {user_temp_folder}\mk698\extraction\NI_LabWindows_CVI_v17\Distributions\CVI\setup.exe
+app62_setup_argument = "{app62_setup_file}\specfile.txt" /qb /r:n /AcceptLicenses yes
+app62_reg_display_name = NI LabWindows/CVI 2017
+app62_reg_type = local_machine
+app62_reg_value = 17
+app62_reg_name = DisplayVersion
+app62_reg_compare = gte
+app62_reboot_computer_at_completion = yes
+
+app7_name = NI 488.2 (v. 17)
+app7_setup_file = {user_temp_folder}\mk698\extraction\NI_4882_v17\setup.exe
+app7_setup_argument = /qb /r:n /AcceptLicenses yes
+app7_reg_display_name = NI-488.2 17.0
+app7_reg_type = local_machine
+app7_reg_value = 17
+app7_reg_name = DisplayVersion
+app7_reg_compare = gte
+app7_reboot_computer_at_completion = yes
+
+app8_name = NI VXI (v. 16)
+app8_setup_file = {user_temp_folder}\mk698\extraction\NI_VXI_v17\setup.exe
+app8_setup_argument = /qb /r:n /AcceptLicenses yes
+app8_reg_display_name = NI-VXI 16.0
+app8_reg_type = local_machine
+app8_reg_value = 16
+app8_reg_name = DisplayVersion
+app8_reg_compare = gte
+app8_reboot_computer_at_completion = yes
+
+app9_name = NI IVI Compliance Package (v. 17)
+app9_setup_file = {user_temp_folder}\mk698\extraction\NI_IVI_Compliance_Package_v17\setup.exe
+app9_setup_argument = /qb /r:n /AcceptLicenses yes
+app9_reg_display_name = NI IVI Compliance Package 17.0
+app9_reg_type = local_machine
+app9_reg_value = 17
+app9_reg_name = DisplayVersion
+app9_reg_compare = gte
+app9_reboot_computer_at_completion = yes
+
+app10_name = NI Serial (v. 17)
+app10_setup_file = {user_temp_folder}\mk698\extraction\NI_Serial_v17\setup.exe
+app10_setup_argument = /qb /r:n /AcceptLicenses yes
+app10_reg_display_name = NI-Serial Runtime 17.0
+app10_reg_type = local_machine
+app10_reg_value = 17
+app10_reg_name = DisplayVersion
+app10_reg_compare = gte
+
+app11_name = NI Switch (v. 17)
+app11_setup_file = {user_temp_folder}\mk698\extraction\NI_Switch_v17\setup.exe
+app11_setup_argument = /qb /r:n /AcceptLicenses yes
+app11_reg_display_name = NI-SWITCH 17.0
+app11_reg_type = local_machine
+app11_reg_value = 17
+app11_reg_name = DisplayVersion
+app11_reg_compare = gte
+app11_reboot_computer_at_completion = yes
+
+app12_name = Sealevel SeaMAX (v3.04)
+app12_setup_file = {user_temp_folder}\mk698\extraction\SeaMAX_v3_04\sx03040001.exe
+app12_setup_argument = -s -f1{user_temp_folder}\mk698\extraction\SeaMAX_v3_04\seamax_install_params.iss
+app12_reg_display_name = SeaMAX
+app12_reg_type = local_machine
+app12_reg_value = 3.4.0.1
+app12_reg_name = DisplayVersion
+app12_reg_compare = gte
+
+;app2_name = Sealevel SeaMACV5 (v5.0.23)
+;app2_setup_file = {user_temp_folder}\mk698\extraction\SeaMACV5_v5_0_23\SM050023.exe
+; app2_setup_argument = -s -f1{user_temp_folder}\mk698\extraction\SeaMACV5_v5_0_23\seamac_install_params.iss
+; app2_reg_display_name = SeaMAC V5
+; app2_reg_type = local_machine
+; app2_reg_value = 5.0.23
+; app2_reg_name = DisplayVersion
+; app2_reg_compare = eq
+
+; app13_name = Sealevel SeaMAC (v5.0.24)
+; app13_setup_file = {user_temp_folder}\mk698\extraction\SeaMAC_v5_0_24\SM050024RC4.exe
+; app13_setup_argument = /S /v/qn
+; app13_reg_display_name = SeaMAC
+; app13_reg_type = local_machine
+; app13_reg_value = 5.0.24
+; app13_reg_name = DisplayVersion
+; app13_reg_compare = eq
+
+app13_name = Sealevel SeaMAC (v6)
+app13_setup_file = {user_temp_folder}\mk698\extraction\SeaMAC_v6\SM060000.exe
+app13_setup_argument = /S /v/qn
+app13_reg_display_name = SeaMAC
+app13_reg_type = local_machine
+app13_reg_value = 6.0
+app13_reg_name = DisplayVersion
+app13_reg_compare = eq
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to run various applications or scripts
+;
+; Possible keys:
+; app#_description (OPTIONAL. Describe the purpose of running this application)
+; app#_path (REQUIRED. Full path and name of the application to be run)
+; - the path can take advantage of using macros. Look below for the available macros
+; app#_is_console (REQUIRED. Specify if the application is a console application (i.e. DOS application)
+; - value is either true/false
+; app#_argument (OPTIONAL. Arguments to be passed to the application)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; - sometimes, the argument maybe include equal sign in them, but we can't have equal sign
+; in the value of the INI. To make it possible, if an equal sign is needed in the ini file
+; use in place of =
+;
+; app#_argument_path# - for each of these keys, there must be a corresponding {app#_argument_path#} defined in the value of app#_argument
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; Example 1:
+; app1_path = C:\ReleaseIB_Production\app.exe
+; app1_arguments = -role Datasrv -suite LSPS3 -production
+;
+; Example 2:
+; app1_description = Extracting ActivePerl archive
+; app1_path = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+;
+; Example 3:
+; app1_description = Extracting ActivePerl archive
+; app1_path = {cd_drive}\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+; ******************************************************************************************************************************
+[Extract_Software_Suite]
+app1_description = Extracting MK698 software suite
+app1_path = {user_temp_folder}\mk698\7-Zip\7z.exe
+app1_is_console = true
+app1_argument = x "{user_temp_folder}\mk698\MK698Software.7z.001" -o"{user_temp_folder}\mk698\extraction" -aos -y
+
+[Extract_Visual_Studio_Archives]
+app1_description = Extracting Visual Studio 2012 Archive
+app1_cd_label = Visual Studio 2012
+app1_path = {cd_drive}\7-Zip\7z.exe
+app1_is_console = true
+app1_argument = x "{cd_drive}\msvs2012.7z" -o"{user_temp_folder}\mk698\extraction\vs2012" -aos -y
+
+app2_description = Extracting Visual Studio 2012 Update 4 Archive
+app2_cd_label = Visual Studio 2012
+app2_path = {cd_drive}\7-Zip\7z.exe
+app2_is_console = true
+app2_argument = x "{cd_drive}\msvs2012_update4.7z" -o"{user_temp_folder}\mk698\extraction\vs2012_update4" -aos -y
+
+[Import_Trusted_Publisher_Certificates]
+app1_description = Importing trusted publisher certificate for SeaLevel SeaMAX Driver
+app1_path = c:\windows\system32\certutil.exe
+app1_is_console = true
+app1_argument = -addstore "TrustedPublisher" "{user_temp_folder}\mk698\extraction\SeaMax_v3_04\pubcert.cer"
+
+app2_description = Importing trusted publisher certificate for SeaLevel SeaMAC Driver
+app2_path = c:\windows\system32\certutil.exe
+app2_is_console = true
+app2_argument = -addstore "TrustedPublisher" "{user_temp_folder}\mk698\extraction\SeaMAC_v6\pubcert.cer"
+
+[Shut_Down_National_Instrument_Processes]
+app1_description = Killing process nierserver.exe
+app1_path = c:\windows\system32\taskkill.exe
+app1_is_console = true
+app1_argument = /f /im nierserver.exe
+
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Modify Network Adapter's settings
+;
+; Possible keys:
+; nic#_pci_location ( REQUIRED.)
+; - the value must be in the form of: #,#,# ( bus, device, function)
+; i.e.: 0,25,0 - bus = 0, device = 25, function = 0
+; nic#_adapter_name (OPTIONAL. Set the name of the network adapter)
+; nic#_ip_and_subnet (OPTIONAL. Set ip address and subnet mask of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,255.255.255.0
+; nic#_default_gateway# (OPTIONAL. Default gateway of the network adapter)
+; - the value must be in the form of: #.#.#.#
+; i.e.: 192.168.0.1
+; nic#_dns_servers (OPTIONAL. Set DNS servers of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,192.168.0.11
+; nic#_link_speed (OPTIONAL. Set the link speed of the network adapter)
+; - Before using this option. Make sure that the network adapter supports link speed setting
+; This is really a registry change for the network adapter. The registry name is *SpeedDuplex
+; The value for *SpeedDuplex is usually a digit ranging from 0-5.
+; Here's an example:
+; 0 - Auto Negotiate
+; 1 - 10Mbps Half Duplex
+; 2 - 10Mbps Full Duplex
+; 3 - 100Mpbs Half Duplex
+; 4 - 100Mbps Full Duplex
+; 6 - 1Gpbs Full Duplex
+; There's no 5 defined because there's no 1Gpbs Half Duplex
+; IMPORTANT: The above example was taken from a Intel network card. These numbers could
+; mean something else different from one network card to the next. Refer to the network
+; adapter's manufacturer manual for the actual numbers and their meanings.
+;
+; nic#_enable_dhcp (OPTIONAL. Set network adapter to use DHCP)
+; - the value must be either: true/false
+; - if this is set to true, all the other settings above, except link speed, will be ignored
+; this will effectively set IP and DNS Servers to be obtained automatically
+;
+; Example 1:
+; nic1_pci_location = 0,25, 0
+; nic1_link_speed = 2
+; nic1_adapter_name = My Connection
+; nic1_enable_dhcp = false
+; nic1_ip_and_subnet = 192.168.0.10 , 255.255.255.0
+; nic1_default_gateway = 192.168.0.1
+; nic1_dns_servers = 192.168.0.5, 192.168.0.6
+;
+; ******************************************************************************************************************************
+[Network_Interface_Cards]
+
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to remove/delete various files or folders
+;
+; Possible keys:
+; item (REQUIRED. This is either a file or folder to be removed)
+;
+; If the item is a folder, user has the option to specify whether or not to delete the folder recursively. To specify to delete
+; a folder recursively, add the word "recursive" right after the path separated by a comma
+;
+; The path can also include user desktop path or temporary folder
+; for desktop path, use macro: {user_desktop}
+; for temporary folder, use macro: {user_temp_folder}
+;
+; Example 1 - Delete a file:
+; item = A:\test\test.hpp
+;
+; Example 2 - Delete a folder recursively:
+; item = A:\test\test2,recursive
+;
+; Example 3 - Delete only the files contained in the folder:
+; item = A:\test\test2
+;
+; Example 4 - Delete a folder on the user's desktop:
+; item = {user_desktop}\test2
+;
+; Example 5 - Delete a folder in the user's temporary folder
+; item = {user_temp_folder}\test2
+; ******************************************************************************************************************************
+[Files_Folders_Removal]
+item = {user_temp_folder}\mk698,recursive
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to copy various packages of files from a source location to destination location
+; Each XML file contains at least 1 package of files. Each file has a source and destination locations
+; Key name can be anything
+; Value must a be a path to a XML file
+;
+; example 1:
+; file_package = package1.xml
+; ******************************************************************************************************************************
+[DVD_Software_Suite]
+file_package = .\PackagesFromCD.xml
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Specify all the paths to be created
+; Possible keys:
+; path (REQUIRED. Valid path to be created)
+;
+; example:
+; path1 = C:\DataIIB\data\Block_IB\CV
+; path2 = C:\DataIIB\data\Block_IB\General\Logs
+; ******************************************************************************************************************************
+[Paths_Creation]
+path = C:\ReleaseIB_Engineering\
+path = C:\ReleaseIB_Production\
+path = C:\DataIB\data\Block_IB\CV
+path = C:\DataIB\data\Block_IB\General\Logs
+path = C:\DataIB\data\Block_IB\General\Scripts
+path = C:\DataIB\data\Block_IB\General\Temp\SingleStepScript
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; To share a folder, must provide path to a folder.
+; Share names are optional as the folder name will be used as the default share name.
+; Any share name defined here will be used as additional share name for its corresponding folder
+; The # in "path#" must match in both keys. A folder can have more than one share name.
+; Possible keys:
+; path# (OPTIONAL. A valid path to be shared)
+; path#_additional_share_names (OPTIONAL. Additional share names associated with a path)
+; - Define one or more shares names separated by comma
+; path#_allowed_accounts ( Windows Built-In, local or domain accounts to be added to the permission list for this share with Full Control )
+; - if this is not defined, this network share will be accessible to everyone with Full Control
+; - if defined, the value must be in the following format:
+; User1,User2,User3 (if more than one account is defined, separate by comma)
+; The account name must either be a built-in window account or local/domain account
+; if the account name is a built-in window account, it can only be one of the following:
+; - everyone, authenticated users
+; if the account name is a local/domain account it must be in this format: DOMAIN\UserAccountName
+;
+; example:
+; path1 = C:\DataIIB\
+; path1_additional_share_names = DataIIB1, DataIIB2
+; path1_allowed_accounts = Authenticated Users,US\1117637
+; path2 = C:\DataIA
+; path2__additional_share_names = DataIA_1
+; path2_allowed_accounts = MYCOMPUTERNAME\Duc
+; path3 = C:\DataIC
+; ******************************************************************************************************************************
+[Paths_Sharing]
+path1 = C:\ReleaseIB_Engineering\
+path2_additional_share_names = Data
+path2 = C:\DataIB\
+path3_additional_share_names = Release
+path3 = C:\ReleaseIB_Production\
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create windows system environment variables
+; the key would be the system environment variable name.
+;
+; Note:
+; Any key defined here will have its valued replaced, except for "path" because path is a window's system environment variable
+; If a key's name is path, the value specified will be appendeding to existing value
+;
+; path can have one or more values separated by commas
+; Example:
+; path = C:\folder1
+; path = C:\folder1, C:\folder2
+; ******************************************************************************************************************************
+[Env_Variables]
+SM3_SEEKER = C:\Development\GUTS\SM3
+; the address of the computer where all the data of each test is saved before being pushed to the network
+SM3_SKR_SERVER = localhost
+; the address of the computer where all test data are pushed to after testing
+SM3_SKR_NETWORK = localhost
+path = C:\Perl\bin\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Add/Modify or Delete registry's key
+;
+; Possible keys:
+; reg#_action ( REQUIRED. What action to perform)
+; - there are only 2 actions ( add/modify, delete)
+; reg#_path (REQUIRED. Registry folder path, not including valuename)
+; reg#_type (REQUIRED)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; reg#_name_value_pair# (Optional. Registry name values and their names)
+; - the registry key defined by registry path can have multiple value names and their associated values
+; - Format of the value: [name:***,value:***,type:***] - replace *** with actual text
+; - name can be anything
+; - value is either numeric or alphanumeric depending on type
+; - type can only be 1 of 4: string, multi_string, dword, qword
+; If type is dword or qword then value can only be numeric
+; If type is multi-string, then format of the value must be:
+; [name:***,:value:***:value:***...,type:multi_string]
+;
+; Example 1:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\MySoftware\
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version,value:3,type:string]
+; reg1_name_value_pair2 = [name:Version2,:value:3:value:34,type:multi-string]
+;
+; Example 2:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+;
+; Example3:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version]
+;
+; Example4:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; ******************************************************************************************************************************
+[Windows_Registry]
+;reg1_action = delete
+;reg1_path = SOFTWARE\Duc\
+;reg1_type = local_machine
+;reg1_name_value_pairs = Versionn[:]3[,]ginrl[:]boy
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create shortcuts on the user's desktop
+;
+; example:
+; shortcut1_name = Data Server
+; shortcut1_target_path = C:\ReleaseIB_Production\app.exe
+; shortcut1_arguments = -role datasrv -suite lsps3 -production
+; ******************************************************************************************************************************
+[Windows_Shortcuts]
+shortcut1_name = Data Server
+shortcut1_target_path = C:\ReleaseIB_Production\app.exe
+shortcut1_arguments = -role datasrv -suite lsps3 -production -no_hw
+
+shortcut2_name = Guts Server
+shortcut2_target_path = C:\ReleaseIB_Production\app.exe
+shortcut2_arguments = -role gutssrv -suite lsps3 -production -no_hw
+
+shortcut3_name = Guts Auto
+shortcut3_target_path = C:\ReleaseIB_Production\app.exe
+shortcut3_arguments = -role auto1b -suite lsps3 -production -no_hw
+
+shortcut4_name = Guts Manual
+shortcut4_target_path = C:\ReleaseIB_Production\app.exe
+shortcut4_arguments = -role gutsman -suite lsps3 -production -no_hw
+
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_NGI.ini b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_NGI.ini
new file mode 100644
index 0000000..c04b92c
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_NGI.ini
@@ -0,0 +1,452 @@
+; ************************************************* SM3 CONFIGURATION FILE *****************************************************
+; Description:
+; This is an INI file which contains the configuration information for the automated setup of either an
+; ENGINEERING or PRODUCTION environment for developing or running SM3 GUTS (Guidance Unit Test Software)
+;
+; Author: Duc Le
+;
+; ******************************************************************************************************************************
+;
+;
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+[General]
+Program_Name = NGI - ComposableTestSoftware Standalone Build Setup
+; 64-bit or 32-bit. Possible values: 32 or 64
+Application_Platform = 32
+
+[Global_Settings]
+Always_Run_Application_Using_Admin_Account = false
+Suppress_All_Prompts = true
+Provide_Windows_Password_For_Auto_Login = false
+
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+; This section defines all the setup steps to be performed and allow the user the option of enabling/disabling each step
+; The key can be anything.
+; The value must define the setup step and its associated section name separated by comma: Setup_Step,Section_Name
+; Below is a list of all possible setup steps:
+; CONFIGURE_NETWORK_ADAPTERS
+; RUN_APPLICATIONS
+; INSTALL_SOFTWARE_PACKAGES
+; ENABLE_INTERNET_INFORMATION_SERVICES
+; CREATE_DIRECTORIES
+; CREATE_NETWORK_SHARES
+; SET_ENVIRONMENT_VARIABLES
+; SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS
+; TRANSFER_FILE_PACKAGES
+; MODIFY_WINDOWS_REGISTRY
+; PROCESS_GUTS_CONFIG_FILE
+; CREATE_WINDOWS_SHORTCUTS
+; ASSIST_BUILDING_GUTS_APP
+; REMOVE_FILES_FOLDERS
+;
+; The setup setup can be run more than once by creating another key and assigned the setup step to it
+; Each setup step needs a section name. Section name provides all the information necessary for the setup step
+; The sequence of the execution of the setup steps will be in the same order as they are specified.
+; ******************************************************************************************************************************
+[Setup_Step_Manager]
+;step = RUN_APPLICATIONS,Extract_Software_Archives
+step = INSTALL_SOFTWARE_PACKAGES,Install_Software
+;step = CREATE_DIRECTORIES,Paths_Creation
+;step = CREATE_NETWORK_SHARES,Paths_Sharing
+;step = SET_ENVIRONMENT_VARIABLES,Env_Variables
+;step = TRANSFER_FILE_PACKAGES,Files_Transfer_Packages
+;step = CREATE_WINDOWS_SHORTCUTS,Windows_Shortcuts
+;step = RUN_APPLICATIONS,Shut_Down_National_Instruments_Processes
+;step = REMOVE_FILES_FOLDERS , Files_Folders_Removal
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to install various software application
+; For each software application to be installed, 4 things can be defined:
+;
+; Possible keys:
+; app#_name (REQUIRED. Name of the application to be installed/checked)
+; app#_setup_file (OPTIONAL. Path and name of the installer)
+; - the setup file can make use of macros. Look below for the available macros
+; app#_setup_argument (OPTIONAL. Argument for the setup file. Usually to perform unattended install)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; app#_setup_confirm_prompt (OPTIONAL. Prompt user to confirm before installation starts.)
+; - possible values: yes, no
+; - yes: there will be prompt asking user confirm/refuse install
+; - no: installation will start automatically ( this is the default )
+; app#_exe_file (REQUIRED only if app#_hklm_reg_key is not specified.
+; This is used to verify that the software successfully installed)
+; app#_reg_path (REQUIRED only if app#_exe_file is not specified. Registry folder path, not including valuename)
+; app#_reg_type (REQUIRED only if app#_reg_key is specified)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; app#_reg_value (REQUIRED only if app#_reg_key is specified. Registry value name's value)
+; app#_reg_name (REQUIRED only if app#_reg_key is specified. Registry value name)
+; app#_reg_compare (REQUIRED only if app#_reg_key is specified. Compare operator between value name's value specified here versus actual value read from registry)
+; - there are only six options for this key ( eq, lt, gt, lte, gte, ne )
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; example 1:
+; app1_name = Perl 5.6.1.638
+; app1_setup_file = {user_temp_folder}\Installer.bat
+; app1_exe_file = C:\Perl\bin\perl.exe
+;
+; example 2:
+; app1_reg_path = SOFTWARE\National Instruments\NI-488.2\CurrentVersion
+; app1_reg_type = local_machine
+; app1_reg_value = 15.0
+; app1_reg_name = Version
+; app1_reg_compare = gte
+; app1_name = National Instrument 488.2 (v15 or higher)
+; app1_setup_file = C:\ni\setup.exe
+;
+; example 3:
+; app1_exe_file = C:\Perl\bin\perl.exe
+; app1_name = Perl 5.6.1.638
+;
+; example 4:
+; app1_name = Sapera LT 8.11 (x64)
+; app1_setup_file = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\Software\TeledyneDalsa\Sapera_LT_8.11_RuntimeSetup.exe
+; app1_setup_argument = -s -f1"{app1_setup_file}\sapera_setup.iss"
+; app1_reg_path = SOFTWARE\Teledyne DALSA\Sapera LT
+; app1_reg_type = local_machine
+; app1_reg_name = IsSaperaFrameGrabberSupport
+;
+; ******************************************************************************************************************************
+; Visual Studio ClassRoot Registry Keys
+;
+; {"VS2005", "VisualStudio.DTE.8.0"},
+; {"VS2008", "VisualStudio.DTE.9.0"},
+; {"VS2010", "VisualStudio.DTE.10.0"},
+; {"VS2012", "VisualStudio.DTE.11.0"},
+; {"VS2013", "VisualStudio.DTE.12.0"},
+; {"VS2015", "VisualStudio.DTE.13.0"}
+;
+; Visual Studio Redistributable Local_Machine Registry Keys
+;
+; {"VS2005_x64", @"SOFTWARE\Classes\Installer\Products\1af2a8da7e60d0b429d7e6453b3d0182"},
+; {"VS2005_x86", @"SOFTWARE\Classes\Installer\Products\c1c4f01781cc94c4c8fb1542c0981a2a"},
+; {"VS2008_x64", @"SOFTWARE\Classes\Installer\Products\67D6ECF5CD5FBA732B8B22BAC8DE1B4D"},
+; {"VS2008_x86", @"SOFTWARE\Classes\Installer\Products\6E815EB96CCE9A53884E7857C57002F0"},
+; {"VS2010_x64", @"SOFTWARE\Classes\Installer\Products\1926E8D15D0BCE53481466615F760A7F"},
+; {"VS2010_x86", @"SOFTWARE\Classes\Installer\Products\1D5E3C0FEDA1E123187686FED06E995A"},
+; {"VS2012_x64", @"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}"},
+; {"VS2012_x86", @"SOFTWARE\Classes\Installer\Dependencies\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f}"},
+; {"VS2013_x64", @"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}"},
+; {"VS2013_x86", @"SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}"},
+; {"VS2015_x64", @"SOFTWARE\Classes\Installer\Dependencies\{3ee5e5bb-b7cc-4556-8861-a00a82977d6c}"},
+; {"VS2015_x86", @"SOFTWARE\Classes\Installer\Dependencies\{23daf363-3020-4059-b3ae-dc4ad39fed19}"}
+;
+; ******************************************************************************************************************************
+[Install_Software]
+app5_name = Visual Studio 2022
+app5_setup_argument = -p --norestart --noweb --add Microsoft.VisualStudio.Workload.ManagedDesktop;includeRecommended Microsoft.VisualStudio.Workload.NativeDesktop;includeRecommended Microsoft.VisualStudio.Component.VC.ATLMFC Microsoft.VisualStudio.Component.VC.CLI.Support Microsoft.VisualStudio.Workload.VisualStudioExtension;includeRecommended
+app5_reg_path = VisualStudio.DTE.17.0
+app5_reg_type = classes_root
+app5_setup_file = D:\Windows_Stuff\Visual_Studio_2022.17.9.5\vs_setup.exe
+app5_install_process_name = setup
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used for enabling windows features
+; Only one thing needs to be defined for this section.
+; - a text file that lists windows feature name line by line
+;
+; Possible keys:
+; feature_list_file
+;
+; example:
+; windows_feature_list_file = .\feature_list.txt
+; ******************************************************************************************************************************
+[Windows_Features]
+windows_feature_list_file = ..\Data\windows_feature_list.txt
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to run various applications or scripts
+;
+; Possible keys:
+; app#_description (OPTIONAL. Describe the purpose of running this application)
+; app#_path (REQUIRED. Full path and name of the application to be run)
+; - the path can take advantage of using macros. Look below for the available macros
+; app#_is_console (REQUIRED. Specify if the application is a console application (i.e. DOS application)
+; - value is either true/false
+; app#_argument (OPTIONAL. Arguments to be passed to the application)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; - sometimes, the argument maybe include equal sign in them, but we can't have equal sign
+; in the value of the INI. To make it possible, if an equal sign is needed in the ini file
+; use in place of =
+;
+; app#_argument_path# - for each of these keys, there must be a corresponding {app#_argument_path#} defined in the value of app#_argument
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; Example 1:
+; app1_path = C:\ReleaseIB_Production\app.exe
+; app1_arguments = -role Datasrv -suite LSPS3 -production
+;
+; Example 2:
+; app1_description = Extracting ActivePerl archive
+; app1_path = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+;
+; Example 3:
+; app1_description = Extracting ActivePerl archive
+; app1_path = {cd_drive}\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+; ******************************************************************************************************************************
+[Extract_Software_Archives]
+;app1_description = Extracting Visual Studio 2012 archive
+;app1_cd_label = GUTS Support Appz 1/2
+;app1_path = {cd_drive}\DISK1\7-Zip\7z.exe
+;app1_is_console = true
+;app1_argument = x "{cd_drive}\DISK1\msvs2012.7z" -o"{user_temp_folder}\vs2012" -y
+
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Modify Network Adapter's settings
+;
+; Possible keys:
+; nic#_pci_location ( REQUIRED.)
+; - the value must be in the form of: #,#,# ( bus, device, function)
+; i.e.: 0,25,0 - bus = 0, device = 25, function = 0
+; nic#_adapter_name (OPTIONAL. Set the name of the network adapter)
+; nic#_ip_and_subnet (OPTIONAL. Set ip address and subnet mask of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,255.255.255.0
+; nic#_default_gateway# (OPTIONAL. Default gateway of the network adapter)
+; - the value must be in the form of: #.#.#.#
+; i.e.: 192.168.0.1
+; nic#_dns_servers (OPTIONAL. Set DNS servers of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,192.168.0.11
+; nic#_link_speed (OPTIONAL. Set the link speed of the network adapter)
+; - Before using this option. Make sure that the network adapter supports link speed setting
+; This is really a registry change for the network adapter. The registry name is *SpeedDuplex
+; The value for *SpeedDuplex is usually a digit ranging from 0-5.
+; Here's an example:
+; 0 - Auto Negotiate
+; 1 - 10Mbps Half Duplex
+; 2 - 10Mbps Full Duplex
+; 3 - 100Mpbs Half Duplex
+; 4 - 100Mbps Full Duplex
+; 6 - 1Gpbs Full Duplex
+; There's no 5 defined because there's no 1Gpbs Half Duplex
+; IMPORTANT: The above example was taken from a Intel network card. These numbers could
+; mean something else different from one network card to the next. Refer to the network
+; adapter's manufacturer manual for the actual numbers and their meanings.
+;
+; nic#_enable_dhcp (OPTIONAL. Set network adapter to use DHCP)
+; - the value must be either: true/false
+; - if this is set to true, all the other settings above, except link speed, will be ignored
+; this will effectively set IP and DNS Servers to be obtained automatically
+;
+; Example 1:
+; nic1_pci_location = 0,25, 0
+; nic1_link_speed = 2
+; nic1_adapter_name = My Connection
+; nic1_enable_dhcp = false
+; nic1_ip_and_subnet = 192.168.0.10 , 255.255.255.0
+; nic1_default_gateway = 192.168.0.1
+; nic1_dns_servers = 192.168.0.5, 192.168.0.6
+;
+; ******************************************************************************************************************************
+[Network_Interface_Cards]
+
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to remove/delete various files or folders
+;
+; Possible keys:
+; item (REQUIRED. This is either a file or folder to be removed)
+;
+; If the item is a folder, user has the option to specify whether or not to delete the folder recursively. To specify to delete
+; a folder recursively, add the word "recursive" right after the path separated by a comma
+;
+; The path can also include user desktop path or temporary folder
+; for desktop path, use macro: {user_desktop}
+; for temporary folder, use macro: {user_temp_folder}
+;
+; Example 1 - Delete a file:
+; item = A:\test\test.hpp
+;
+; Example 2 - Delete a folder recursively:
+; item = A:\test\test2,recursive
+;
+; Example 3 - Delete only the files contained in the folder:
+; item = A:\test\test2
+;
+; Example 4 - Delete a folder on the user's desktop:
+; item = {user_desktop}\test2
+;
+; Example 5 - Delete a folder in the user's temporary folder
+; item = {user_temp_folder}\test2
+; ******************************************************************************************************************************
+[Files_Folders_Removal]
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to copy various packages of files from a source location to destination location
+; Each XML file contains at least 1 package of files. Each file has a source and destination locations
+; Key name can be anything
+; Value must a be a path to a XML file
+;
+; example 1:
+; file_package = package1.xml
+; ******************************************************************************************************************************
+[Files_Transfer_Packages]
+file_package = ..\CTS\file_package.xml
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Specify all the paths to be created
+; Possible keys:
+; path (REQUIRED. Valid path to be created)
+;
+; example:
+; path1 = C:\DataIIB\data\Block_IB\CV
+; path2 = C:\DataIIB\data\Block_IB\General\Logs
+; ******************************************************************************************************************************
+[Paths_Creation]
+path = C:\ReleaseIB_Engineering\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; To share a folder, must provide path to a folder.
+; Share names are optional as the folder name will be used as the default share name.
+; Any share name defined here will be used as additional share name for its corresponding folder
+; The # in "path#" must match in both keys. A folder can have more than one share name.
+; Possible keys:
+; path# (OPTIONAL. A valid path to be shared)
+; path#_additional_share_names (OPTIONAL. Additional share names associated with a path)
+; - Define one or more shares names separated by comma
+; path#_allowed_accounts ( Windows Built-In, local or domain accounts to be added to the permission list for this share with Full Control )
+; - if this is not defined, this network share will be accessible to everyone with Full Control
+; - if defined, the value must be in the following format:
+; User1,User2,User3 (if more than one account is defined, separate by comma)
+; The account name must either be a built-in window account or local/domain account
+; if the account name is a built-in window account, it can only be one of the following:
+; - everyone, authenticated users
+; if the account name is a local/domain account it must be in this format: DOMAIN\UserAccountName
+;
+; example:
+; path1 = C:\DataIIB\
+; path1_additional_share_names = DataIIB1, DataIIB2
+; path1_allowed_accounts = Authenticated Users,US\1117637
+; path2 = C:\DataIA
+; path2__additional_share_names = DataIA_1
+; path2_allowed_accounts = MYCOMPUTERNAME\Duc
+; path3 = C:\DataIC
+; ******************************************************************************************************************************
+[Paths_Sharing]
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create windows system environment variables
+; the key would be the system environment variable name.
+;
+; Note:
+; Any key defined here will have its valued replaced, except for "path" because path is a window's system environment variable
+; If a key's name is path, the value specified will be appendeding to existing value
+;
+; path can have one or more values separated by commas
+; Example:
+; path = C:\folder1
+; path = C:\folder1, C:\folder2
+; ******************************************************************************************************************************
+[Env_Variables]
+SM3_SEEKER = C:\Development\GUTS\SM3
+; the address of the computer where all the data of each test is saved before being pushed to the network
+SM3_SKR_SERVER = localhost
+; the address of the computer where all test data are pushed to after testing
+SM3_SKR_NETWORK = localhost
+path = C:\Perl\bin\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Add/Modify or Delete registry's key
+;
+; Possible keys:
+; reg#_action ( REQUIRED. What action to perform)
+; - there are only 2 actions ( add/modify, delete)
+; reg#_path (REQUIRED. Registry folder path, not including valuename)
+; reg#_type (REQUIRED)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; reg#_name_value_pair# (Optional. Registry name values and their names)
+; - the registry key defined by registry path can have multiple value names and their associated values
+; - Format of the value: [name:***,value:***,type:***] - replace *** with actual text
+; - name can be anything
+; - value is either numeric or alphanumeric depending on type
+; - type can only be 1 of 4: string, multi_string, dword, qword
+; If type is dword or qword then value can only be numeric
+; If type is multi-string, then format of the value must be:
+; [name:***,:value:***:value:***...,type:multi_string]
+;
+; Example 1:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\MySoftware\
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version,value:3,type:string]
+; reg1_name_value_pair2 = [name:Version2,:value:3:value:34,type:multi-string]
+;
+; Example 2:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+;
+; Example3:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version]
+;
+; Example4:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; ******************************************************************************************************************************
+[Windows_Registry]
+;reg1_action = delete
+;reg1_path = SOFTWARE\Duc\
+;reg1_type = local_machine
+;reg1_name_value_pairs = Versionn[:]3[,]ginrl[:]boy
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create shortcuts on the user's desktop
+;
+; example:
+; shortcut1_name = Data Server
+; shortcut1_target_path = C:\ReleaseIB_Production\app.exe
+; shortcut1_arguments = -role datasrv -suite lsps3 -production
+; ******************************************************************************************************************************
+[Windows_Shortcuts]
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_control_pc.ini b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_control_pc.ini
new file mode 100644
index 0000000..f3b9492
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_control_pc.ini
@@ -0,0 +1,599 @@
+; ************************************************* SM3 CONFIGURATION FILE *****************************************************
+; Description:
+; This is an INI file which contains the configuration information for the automated setup of either an
+; ENGINEERING or PRODUCTION environment for developing or running SM3 GUTS (Guidance Unit Test Software)
+;
+; Author: Duc Le
+;
+; ******************************************************************************************************************************
+;
+;
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+[General]
+Program_Name = SM3 Block IB - Control PC
+; 64-bit or 32-bit. Possible values: 32 or 64
+Application_Platform = 32
+
+[Global_Settings]
+Always_Run_Application_Using_Admin_Account = true
+Suppress_All_Prompts = true
+Provide_Windows_Password_For_Auto_Login = false
+
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+; This section defines all the setup steps to be performed and allow the user the option of enabling/disabling each step
+; The key can be anything.
+; The value must define the setup step and its associated section name separated by comma: Setup_Step,Section_Name
+; Below is a list of all possible setup steps:
+; CONFIGURE_NETWORK_ADAPTERS
+; RUN_APPLICATIONS
+; INSTALL_SOFTWARE_PACKAGES
+; ENABLE_INTERNET_INFORMATION_SERVICES
+; CREATE_DIRECTORIES
+; CREATE_NETWORK_SHARES
+; SET_ENVIRONMENT_VARIABLES
+; SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS
+; TRANSFER_FILE_PACKAGES
+; MODIFY_WINDOWS_REGISTRY
+; PROCESS_GUTS_CONFIG_FILE
+; CREATE_WINDOWS_SHORTCUTS
+; ASSIST_BUILDING_GUTS_APP
+; REMOVE_FILES_FOLDERS
+;
+; The setup setup can be run more than once by creating another key and assigned the setup step to it
+; Each setup step needs a section name. Section name provides all the information necessary for the setup step
+; The sequence of the execution of the setup steps will be in the same order as they are specified.
+; ******************************************************************************************************************************
+[Setup_Step_Manager]
+step = INSTALL_SOFTWARE_PACKAGES,Install_VS2012
+step = INSTALL_SOFTWARE_PACKAGES,Install_VS2012_Update4
+step = INSTALL_SOFTWARE_PACKAGES,Install_4882
+step = INSTALL_SOFTWARE_PACKAGES,Install_VXI
+step = INSTALL_SOFTWARE_PACKAGES,Install_Perl
+step = INSTALL_SOFTWARE_PACKAGES,Install_Redist2013
+step = RUN_APPLICATIONS,Enable_Network_Sharing
+step = CREATE_DIRECTORIES,Paths_Creation
+step = CREATE_NETWORK_SHARES,Paths_Sharing
+step = SET_ENVIRONMENT_VARIABLES,Env_Variables
+step = TRANSFER_FILE_PACKAGES,Files_Transfer_Packages
+step = MODIFY_WINDOWS_REGISTRY,Windows_Registry
+step = CONFIGURE_NETWORK_ADAPTERS,Network_Interface_Cards
+step = CREATE_WINDOWS_SHORTCUTS,Windows_Shortcuts
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to install various software application
+; For each software application to be installed, 4 things can be defined:
+;
+; Possible keys:
+; app#_name (REQUIRED. Name of the application to be installed/checked)
+; app#_setup_file (OPTIONAL. Path and name of the installer)
+; - the setup file can make use of macros. Look below for the available macros
+; app#_setup_argument (OPTIONAL. Argument for the setup file. Usually to perform unattended install)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; app#_setup_confirm_prompt (OPTIONAL. Prompt user to confirm before installation starts.)
+; - possible values: yes, no
+; - yes: there will be prompt asking user confirm/refuse install
+; - no: installation will start automatically ( this is the default )
+; app#_exe_file (REQUIRED only if app#_hklm_reg_key is not specified.
+; This is used to verify that the software successfully installed)
+; app#_reg_path (REQUIRED only if app#_exe_file is not specified. Registry folder path, not including valuename)
+; app#_reg_type (REQUIRED only if app#_reg_key is specified)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; app#_reg_value (REQUIRED only if app#_reg_key is specified. Registry value name's value)
+; app#_reg_name (REQUIRED only if app#_reg_key is specified. Registry value name)
+; app#_reg_compare (REQUIRED only if app#_reg_key is specified. Compare operator between value name's value specified here versus actual value read from registry)
+; - there are only six options for this key ( eq, lt, gt, lte, gte, ne )
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; example 1:
+; app1_name = Perl 5.6.1.638
+; app1_setup_file = {user_temp_folder}\Installer.bat
+; app1_exe_file = C:\Perl\bin\perl.exe
+;
+; example 2:
+; app1_reg_path = SOFTWARE\National Instruments\NI-488.2\CurrentVersion
+; app1_reg_type = local_machine
+; app1_reg_value = 15.0
+; app1_reg_name = Version
+; app1_reg_compare = gte
+; app1_name = National Instrument 488.2 (v15 or higher)
+; app1_setup_file = C:\ni\setup.exe
+;
+; example 3:
+; app1_exe_file = C:\Perl\bin\perl.exe
+; app1_name = Perl 5.6.1.638
+;
+; example 4:
+; app1_name = Sapera LT 8.11 (x64)
+; app1_setup_file = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\Software\TeledyneDalsa\Sapera_LT_8.11_RuntimeSetup.exe
+; app1_setup_argument = -s -f1"{app1_setup_file}\sapera_setup.iss"
+; app1_reg_path = SOFTWARE\Teledyne DALSA\Sapera LT
+; app1_reg_type = local_machine
+; app1_reg_name = IsSaperaFrameGrabberSupport
+;
+; ******************************************************************************************************************************
+; Visual Studio ClassRoot Registry Keys
+;
+; {"VS2005", "VisualStudio.DTE.8.0"},
+; {"VS2008", "VisualStudio.DTE.9.0"},
+; {"VS2010", "VisualStudio.DTE.10.0"},
+; {"VS2012", "VisualStudio.DTE.11.0"},
+; {"VS2013", "VisualStudio.DTE.12.0"},
+; {"VS2015", "VisualStudio.DTE.13.0"}
+;
+; Visual Studio Redistributable Local_Machine Registry Keys
+;
+; {"VS2005_x64", @"SOFTWARE\Classes\Installer\Products\1af2a8da7e60d0b429d7e6453b3d0182"},
+; {"VS2005_x86", @"SOFTWARE\Classes\Installer\Products\c1c4f01781cc94c4c8fb1542c0981a2a"},
+; {"VS2008_x64", @"SOFTWARE\Classes\Installer\Products\67D6ECF5CD5FBA732B8B22BAC8DE1B4D"},
+; {"VS2008_x86", @"SOFTWARE\Classes\Installer\Products\6E815EB96CCE9A53884E7857C57002F0"},
+; {"VS2010_x64", @"SOFTWARE\Classes\Installer\Products\1926E8D15D0BCE53481466615F760A7F"},
+; {"VS2010_x86", @"SOFTWARE\Classes\Installer\Products\1D5E3C0FEDA1E123187686FED06E995A"},
+; {"VS2012_x64", @"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}"},
+; {"VS2012_x86", @"SOFTWARE\Classes\Installer\Dependencies\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f}"},
+; {"VS2013_x64", @"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}"},
+; {"VS2013_x86", @"SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}"},
+; {"VS2015_x64", @"SOFTWARE\Classes\Installer\Dependencies\{3ee5e5bb-b7cc-4556-8861-a00a82977d6c}"},
+; {"VS2015_x86", @"SOFTWARE\Classes\Installer\Dependencies\{23daf363-3020-4059-b3ae-dc4ad39fed19}"}
+;
+; ******************************************************************************************************************************
+[Install_VS2012]
+app5_name = Visual Studio 2012
+app5_setup_argument = /passive /norestart
+app5_reg_path = VisualStudio.DTE.11.0
+app5_reg_type = classes_root
+app5_setup_file = ..\Data\software\Visual_Studio_2012\vs_professional.exe
+
+[Install_VS2012_Update4]
+app6_name = Visual Studio 2012 - Update 4
+app6_setup_file = ..\Data\software\Visual_Studio_2012_Update_4\VS2012.4.exe
+app6_setup_argument = /passive /norestart
+app6_reg_path = SOFTWARE\Wow6432Node\Microsoft\DevDiv\vc\Servicing\11.0\CompilerCore\1033
+app6_reg_type = local_machine
+app6_reg_value = 11.0.61030
+app6_reg_name = UpdateVersion
+app6_reg_compare = eq
+
+[Install_4882]
+app2_name = National Instrument 488.2 (ver. 17)
+app2_setup_file = ..\Data\software\NI_4882_v17\setup.exe
+app2_setup_argument = /qb /r:n /AcceptLicenses yes
+app2_reg_display_name = NI-488.2 17.0
+app2_reg_type = local_machine
+app2_reg_value = 17
+app2_reg_name = DisplayVersion
+app2_reg_compare = gte
+app2_reboot_computer_at_completion = yes
+app2_exit_codes_to_ignore = 3010
+
+[Install_VXI]
+app3_name = National Instrument VXI (ver. 16)
+app3_setup_file = ..\Data\software\NI_VXI_v17\setup.exe
+app3_setup_argument = /qb /r:n /AcceptLicenses yes
+app3_reg_display_name = NI-VXI 16.0
+app3_reg_type = local_machine
+app3_reg_value = 16
+app3_reg_name = DisplayVersion
+app3_reg_compare = gte
+app3_reboot_computer_at_completion = yes
+app3_exit_codes_to_ignore = 3010
+
+[Install_Perl]
+;app1_setup_confirm_prompt = yes
+app1_name = ActivePerl 5.6.1.638
+app1_setup_file = ..\Data\software\Perl_5_6\Installer_Silent.bat
+app1_exe_file = C:\Perl\bin\perl.exe
+
+[Install_Redist2013]
+app4_name = Visual Studio Redistributable 2013 (x86)
+app4_setup_file = ..\Data\software\VS2013_Redistributable\vcredist_x86.EXE
+app4_setup_argument = /install /passive /norestart
+app4_reg_path = SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}
+app4_reg_type = local_machine
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used for enabling windows features
+; Only one thing needs to be defined for this section.
+; - a text file that lists windows feature name line by line
+;
+; Possible keys:
+; feature_list_file
+;
+; example:
+; windows_feature_list_file = .\feature_list.txt
+; ******************************************************************************************************************************
+[Windows_Features]
+windows_feature_list_file = .\Repository\windows_feature_list.txt
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to run various applications or scripts
+;
+; Possible keys:
+; app#_description (OPTIONAL. Describe the purpose of running this application)
+; app#_path (REQUIRED. Full path and name of the application to be run)
+; - the path can take advantage of using macros. Look below for the available macros
+; app#_is_console (REQUIRED. Specify if the application is a console application (i.e. DOS application)
+; - value is either true/false
+; app#_argument (OPTIONAL. Arguments to be passed to the application)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; - sometimes, the argument maybe include equal sign in them, but we can't have equal sign
+; in the value of the INI. To make it possible, if an equal sign is needed in the ini file
+; use in place of =
+;
+; app#_argument_path# - for each of these keys, there must be a corresponding {app#_argument_path#} defined in the value of app#_argument
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; Example 1:
+; app1_path = C:\ReleaseIB_Production\app.exe
+; app1_arguments = -role Datasrv -suite LSPS3 -production
+;
+; Example 2:
+; app1_description = Extracting ActivePerl archive
+; app1_path = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+;
+; Example 3:
+; app1_description = Extracting ActivePerl archive
+; app1_path = {cd_drive}\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+; ******************************************************************************************************************************
+[Enable_Network_Sharing]
+app3_description = Enabling Network Discovery
+app3_path = c:\windows\system32\netsh.exe
+app3_is_console = true
+app3_argument = advfirewall firewall set rule group"Network Discovery" new enableYes
+
+app4_description = Enabling File and Printer Sharing
+app4_path = c:\windows\system32\netsh.exe
+app4_is_console = true
+app4_argument = advfirewall firewall set rule group"File and Printer Sharing" new enableYes
+
+[Extract_Software_Archives]
+app1_description = Extracting Visual Studio 2012 archive
+app1_cd_label = GUTS Support Appz 1/2
+app1_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app1_is_console = true
+app1_argument = x "{cd_drive}\DISK1\msvs2012.7z" -o"{user_temp_folder}\vs2012" -y
+
+app2_description = Extracting Visual Studio 2012 Update 4 archive
+app2_cd_label = GUTS Support Appz 1/2
+app2_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app2_is_console = true
+app2_argument = x "{cd_drive}\DISK1\msvs2012_update4.7z" -o"{user_temp_folder}\vs2012_update4" -y
+
+app3_description = Extracting NI 488.2 archive
+app3_cd_label = GUTS Support Appz 1/2
+app3_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app3_is_console = true
+app3_argument = x "{cd_drive}\DISK1\ni4882.7z" -o"{user_temp_folder}\ni4882" -y
+
+app4_description = Extracting NI VXI archive
+app4_cd_label = GUTS Support Appz 1/2
+app4_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app4_is_console = true
+app4_argument = x "{cd_drive}\DISK1\nivxi.7z" -o"{user_temp_folder}\nivxi" -y
+
+app5_description = Extracting ActivePerl archive
+app5_cd_label = GUTS Support Appz 1/2
+app5_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app5_is_console = true
+app5_argument = x "{cd_drive}\DISK1\Perl.7z" -o"{user_temp_folder}" -y
+
+[Shut_Down_National_Instruments_Processes]
+app1_description = Killing process nierserver.exe
+app1_path = C:\Windows\system32\taskkill.exe
+app1_is_console = true
+app1_argument = /f /im nierserver.exe
+
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Modify Network Adapter's settings
+;
+; Possible keys:
+; nic#_pci_location ( REQUIRED.)
+; - the value must be in the form of: #,#,# ( bus, device, function)
+; i.e.: 0,25,0 - bus = 0, device = 25, function = 0
+; nic#_adapter_name (OPTIONAL. Set the name of the network adapter)
+; nic#_ip_and_subnet (OPTIONAL. Set ip address and subnet mask of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,255.255.255.0
+; nic#_default_gateway# (OPTIONAL. Default gateway of the network adapter)
+; - the value must be in the form of: #.#.#.#
+; i.e.: 192.168.0.1
+; nic#_dns_servers (OPTIONAL. Set DNS servers of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,192.168.0.11
+; nic#_link_speed (OPTIONAL. Set the link speed of the network adapter)
+; - Before using this option. Make sure that the network adapter supports link speed setting
+; This is really a registry change for the network adapter. The registry name is *SpeedDuplex
+; The value for *SpeedDuplex is usually a digit ranging from 0-5.
+; Here's an example:
+; 0 - Auto Negotiate
+; 1 - 10Mbps Half Duplex
+; 2 - 10Mbps Full Duplex
+; 3 - 100Mpbs Half Duplex
+; 4 - 100Mbps Full Duplex
+; 6 - 1Gpbs Full Duplex
+; There's no 5 defined because there's no 1Gpbs Half Duplex
+; IMPORTANT: The above example was taken from a Intel network card. These numbers could
+; mean something else different from one network card to the next. Refer to the network
+; adapter's manufacturer manual for the actual numbers and their meanings.
+;
+; nic#_enable_dhcp (OPTIONAL. Set network adapter to use DHCP)
+; - the value must be either: true/false
+; - if this is set to true, all the other settings above, except link speed, will be ignored
+; this will effectively set IP and DNS Servers to be obtained automatically
+;
+; Example 1:
+; nic1_pci_location = 0,25, 0
+; nic1_link_speed = 2
+; nic1_adapter_name = My Connection
+; nic1_enable_dhcp = false
+; nic1_ip_and_subnet = 192.168.0.10 , 255.255.255.0
+; nic1_default_gateway = 192.168.0.1
+; nic1_dns_servers = 192.168.0.5, 192.168.0.6
+;
+; ******************************************************************************************************************************
+[Network_Interface_Cards]
+nic1_pci_location = 20,0,0
+nic1_adapter_name = Private_top
+nic1_ip_and_subnet = 192.168.1.12 , 255.255.255.0
+
+nic2_pci_location = 20,0,1
+nic2_adapter_name = Public_bottom
+nic2_enable_dhcp = true
+
+nic3_pci_location = 5,0,0
+nic3_adapter_name = Spare_side_port
+nic3_enable_dhcp = true
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to remove/delete various files or folders
+;
+; Possible keys:
+; item (REQUIRED. This is either a file or folder to be removed)
+;
+; If the item is a folder, user has the option to specify whether or not to delete the folder recursively. To specify to delete
+; a folder recursively, add the word "recursive" right after the path separated by a comma
+;
+; The path can also include user desktop path or temporary folder
+; for desktop path, use macro: {user_desktop}
+; for temporary folder, use macro: {user_temp_folder}
+;
+; Example 1 - Delete a file:
+; item = A:\test\test.hpp
+;
+; Example 2 - Delete a folder recursively:
+; item = A:\test\test2,recursive
+;
+; Example 3 - Delete only the files contained in the folder:
+; item = A:\test\test2
+;
+; Example 4 - Delete a folder on the user's desktop:
+; item = {user_desktop}\test2
+;
+; Example 5 - Delete a folder in the user's temporary folder
+; item = {user_temp_folder}\test2
+; ******************************************************************************************************************************
+[Files_Folders_Removal]
+item = {user_temp_folder}\perl,recursive
+item = {user_temp_folder}\vs2012,recursive
+item = {user_temp_folder}\vs2012_update4,recursive
+item = {user_temp_folder}\ni4882,recursive
+item = {user_temp_folder}\nivxi,recursive
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to copy various packages of files from a source location to destination location
+; Each XML file contains at least 1 package of files. Each file has a source and destination locations
+; Key name can be anything
+; Value must a be a path to a XML file
+;
+; example 1:
+; file_package = package1.xml
+; ******************************************************************************************************************************
+[Files_Transfer_Packages]
+file_package = ..\Data\software\control_pc_software_package.xml
+file_package = ..\Data\support_files\control_pc_support_package.xml
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Specify all the paths to be created
+; Possible keys:
+; path (REQUIRED. Valid path to be created)
+;
+; example:
+; path = C:\DataIIB\data\Block_IB\CV
+; path = C:\DataIIB\data\Block_IB\General\Logs
+; ******************************************************************************************************************************
+[Paths_Creation]
+path = D:\ReleaseIB_Engineering\
+path = D:\ReleaseIB_Production\
+path = D:\Development
+path = D:\DataIB\data\Block_IB\CV
+path = D:\DataIB\data\Block_IB\General\Logs
+path = D:\DataIB\data\Block_IB\General\Scripts
+path = D:\DataIB\data\Block_IB\General\Temp\SingleStepScript
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; To share a folder, must provide path to a folder.
+; Share names are optional as the folder name will be used as the default share name.
+; Any share name defined here will be used as additional share name for its corresponding folder
+; The # in "path#" must match in both keys. A folder can have more than one share name.
+; Possible keys:
+; path# (OPTIONAL. A valid path to be shared)
+; path#_additional_share_names (OPTIONAL. Additional share names associated with a path)
+; - Define one or more shares names separated by comma
+; path#_allowed_accounts ( Windows Built-In, local or domain accounts to be added to the permission list for this share with Full Control )
+; - if this is not defined, this network share will be accessible to everyone with Full Control
+; - if defined, the value must be in the following format:
+; User1,User2,User3 (if more than one account is defined, separate by comma)
+; The account name must either be a built-in window account or local/domain account
+; if the account name is a built-in window account, it can only be one of the following:
+; - everyone, authenticated users
+; if the account name is a local/domain account it must be in this format: DOMAIN\UserAccountName
+;
+; example:
+; path1 = C:\DataIIB\
+; path1_additional_share_names = DataIIB1, DataIIB2
+; path1_allowed_accounts = Authenticated Users,US\1117637
+; path2 = C:\DataIA
+; path2__additional_share_names = DataIA_1
+; path2_allowed_accounts = MYCOMPUTERNAME\Duc
+; path3 = C:\DataIC
+; ******************************************************************************************************************************
+[Paths_Sharing]
+path1 = D:\ReleaseIB_Engineering\
+path1_allowed_accounts = Authenticated Users
+
+path2 = D:\DataIB\
+path2_allowed_accounts = Authenticated Users
+
+path3 = D:\ReleaseIB_Production\
+path3_allowed_accounts = Authenticated Users
+
+path4 = D:\Development\
+path4_allowed_accounts = Authenticated Users
+
+path5 = C:\
+path5_allowed_accounts = Authenticated Users
+
+path6 = D:\
+path6_allowed_accounts = Authenticated Users
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create windows system environment variables
+; the key would be the system environment variable name.
+;
+; Note:
+; Any key defined here will have its valued replaced, except for "path" because path is a window's system environment variable
+; If a key's name is path, the value specified will be appending to existing value
+;
+; path can have one or more values separated by commas
+; Example:
+; path = C:\folder1
+; path = C:\folder1, C:\folder2
+; ******************************************************************************************************************************
+[Env_Variables]
+; the address of the computer where all the data of each test is saved before being pushed to the network
+SM3_SKR_SERVER = ste_control_local
+; the address of the computer where all test data are pushed to after testing
+SM3_SKR_NETWORK = sm3na02
+path = C:\Perl\bin\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Add/Modify or Delete registry's key
+;
+; Possible keys:
+; reg#_action ( REQUIRED. What action to perform)
+; - there are only 2 actions ( add/modify, delete)
+; reg#_path (REQUIRED. Registry folder path, not including valuename)
+; reg#_type (REQUIRED)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; reg#_name_value_pair# (Optional. Registry name values and their names)
+; - the registry key defined by registry path can have multiple value names and their associated values
+; - Format of the value: [name:***,value:***,type:***] - replace *** with actual text
+; - name can be anything
+; - value is either numeric or alphanumeric depending on type
+; - type can only be 1 of 4: string, multi_string, dword, qword
+; If type is dword or qword then value can only be numeric
+; If type is multi-string, then format of the value must be:
+; [name:***,:value:***:value:***...,type:multi_string]
+;
+; Example 1:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\MySoftware\
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version,value:3,type:string]
+; reg1_name_value_pair2 = [name:Version2,:value:3:value:34,type:multi-string]
+;
+; Example 2:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+;
+; Example3:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version]
+;
+; Example4:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; ******************************************************************************************************************************
+[Windows_Registry]
+reg1_action = add/modify
+reg1_path = SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
+reg1_type = local_machine
+reg1_name_value_pair1 = [name:BackConnectionHostNames,:value:ste_control_local,type:multi_string]
+
+reg2_action = add/modify
+reg2_path = SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
+reg2_type = local_machine
+reg2_name_value_pair1 = [name:DisableStrictNameChecking,value:1,type:dword]
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create shortcuts on the user's desktop
+;
+; example:
+; shortcut1_name = Data Server
+; shortcut1_target_path = C:\ReleaseIB_Production\app.exe
+; shortcut1_arguments = -role datasrv -suite lsps3 -production
+; ******************************************************************************************************************************
+[Windows_Shortcuts]
+shortcut1_name = GUTS Startup
+shortcut1_target_path = C:\Perl\bin\perl.exe
+shortcut1_arguments = D:\ReleaseIB_Production\startup.pl
+shortcut1_for_all_users = true
+
+shortcut2_name = WidebandAccount
+shortcut2_target_path = D:\ReleaseIB_Production\WidebandAccount.bat
+shortcut2_for_all_users = true
+
+shortcut3_name = Resman
+shortcut3_target_path = C:\Program Files (x86)\National Instruments\VXI\Resman.exe
+shortcut3_for_all_users = true
+
+
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_dev_pc.ini b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_dev_pc.ini
new file mode 100644
index 0000000..bcac99f
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_dev_pc.ini
@@ -0,0 +1,596 @@
+; ************************************************* SM3 CONFIGURATION FILE *****************************************************
+; Description:
+; This is an INI file which contains the configuration information for the automated setup of either an
+; ENGINEERING or PRODUCTION environment for developing or running SM3 GUTS (Guidance Unit Test Software)
+;
+; Author: Duc Le
+;
+; ******************************************************************************************************************************
+;
+;
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+[General]
+Program_Name = SM3 Block IB - Dev PC
+; 64-bit or 32-bit. Possible values: 32 or 64
+Application_Platform = 32
+
+[Global_Settings]
+Always_Run_Application_Using_Admin_Account = true
+Suppress_All_Prompts = true
+Provide_Windows_Password_For_Auto_Login = false
+
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+; This section defines all the setup steps to be performed and allow the user the option of enabling/disabling each step
+; The key can be anything.
+; The value must define the setup step and its associated section name separated by comma: Setup_Step,Section_Name
+; Below is a list of all possible setup steps:
+; CONFIGURE_NETWORK_ADAPTERS
+; RUN_APPLICATIONS
+; INSTALL_SOFTWARE_PACKAGES
+; ENABLE_INTERNET_INFORMATION_SERVICES
+; CREATE_DIRECTORIES
+; CREATE_NETWORK_SHARES
+; SET_ENVIRONMENT_VARIABLES
+; SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS
+; TRANSFER_FILE_PACKAGES
+; MODIFY_WINDOWS_REGISTRY
+; PROCESS_GUTS_CONFIG_FILE
+; CREATE_WINDOWS_SHORTCUTS
+; ASSIST_BUILDING_GUTS_APP
+; REMOVE_FILES_FOLDERS
+;
+; The setup setup can be run more than once by creating another key and assigned the setup step to it
+; Each setup step needs a section name. Section name provides all the information necessary for the setup step
+; The sequence of the execution of the setup steps will be in the same order as they are specified.
+; ******************************************************************************************************************************
+[Setup_Step_Manager]
+step = RUN_APPLICATIONS,Import_Trusted_Publisher_Certificates
+step = INSTALL_SOFTWARE_PACKAGES,Install_VS2012
+step = INSTALL_SOFTWARE_PACKAGES,Install_VS2012_Update4
+step = INSTALL_SOFTWARE_PACKAGES,Install_Sapera
+step = INSTALL_SOFTWARE_PACKAGES,Install_PX4_Driver
+step = INSTALL_SOFTWARE_PACKAGES,Install_LabWindows_CVI
+step = RUN_APPLICATIONS,Enable_Network_Sharing
+step = CREATE_DIRECTORIES,Paths_Creation
+step = CREATE_NETWORK_SHARES,Paths_Sharing
+step = MODIFY_WINDOWS_REGISTRY,Windows_Registry
+step = CONFIGURE_NETWORK_ADAPTERS,Network_Interface_Cards
+step = TRANSFER_FILE_PACKAGES,Files_Transfer_Packages
+step = CREATE_WINDOWS_SHORTCUTS,Windows_Shortcuts
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to install various software application
+; For each software application to be installed, 4 things can be defined:
+;
+; Possible keys:
+; app#_name (REQUIRED. Name of the application to be installed/checked)
+; app#_setup_file (OPTIONAL. Path and name of the installer)
+; - the setup file can make use of macros. Look below for the available macros
+; app#_setup_argument (OPTIONAL. Argument for the setup file. Usually to perform unattended install)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; app#_setup_confirm_prompt (OPTIONAL. Prompt user to confirm before installation starts.)
+; - possible values: yes, no
+; - yes: there will be prompt asking user confirm/refuse install
+; - no: installation will start automatically ( this is the default )
+; app#_exe_file (REQUIRED only if app#_hklm_reg_key is not specified.
+; This is used to verify that the software successfully installed)
+; app#_reg_path (REQUIRED only if app#_exe_file is not specified. Registry folder path, not including valuename)
+; app#_reg_type (REQUIRED only if app#_reg_key is specified)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; app#_reg_value (REQUIRED only if app#_reg_key is specified. Registry value name's value)
+; app#_reg_name (REQUIRED only if app#_reg_key is specified. Registry value name)
+; app#_reg_compare (REQUIRED only if app#_reg_key is specified. Compare operator between value name's value specified here versus actual value read from registry)
+; - there are only six options for this key ( eq, lt, gt, lte, gte, ne )
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; example 1:
+; app1_name = Perl 5.6.1.638
+; app1_setup_file = {user_temp_folder}\Installer.bat
+; app1_exe_file = C:\Perl\bin\perl.exe
+;
+; example 2:
+; app1_reg_path = SOFTWARE\National Instruments\NI-488.2\CurrentVersion
+; app1_reg_type = local_machine
+; app1_reg_value = 15.0
+; app1_reg_name = Version
+; app1_reg_compare = gte
+; app1_name = National Instrument 488.2 (v15 or higher)
+; app1_setup_file = C:\ni\setup.exe
+;
+; example 3:
+; app1_exe_file = C:\Perl\bin\perl.exe
+; app1_name = Perl 5.6.1.638
+;
+; example 4:
+; app1_name = Sapera LT 8.11 (x64)
+; app1_setup_file = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\Software\TeledyneDalsa\Sapera_LT_8.11_RuntimeSetup.exe
+; app1_setup_argument = -s -f1"{app1_setup_file}\sapera_setup.iss"
+; app1_reg_path = SOFTWARE\Teledyne DALSA\Sapera LT
+; app1_reg_type = local_machine
+; app1_reg_name = IsSaperaFrameGrabberSupport
+;
+; ******************************************************************************************************************************
+; Visual Studio ClassRoot Registry Keys
+;
+; {"VS2005", "VisualStudio.DTE.8.0"},
+; {"VS2008", "VisualStudio.DTE.9.0"},
+; {"VS2010", "VisualStudio.DTE.10.0"},
+; {"VS2012", "VisualStudio.DTE.11.0"},
+; {"VS2013", "VisualStudio.DTE.12.0"},
+; {"VS2015", "VisualStudio.DTE.13.0"}
+;
+; Visual Studio Redistributable Local_Machine Registry Keys
+;
+; {"VS2005_x64", @"SOFTWARE\Classes\Installer\Products\1af2a8da7e60d0b429d7e6453b3d0182"},
+; {"VS2005_x86", @"SOFTWARE\Classes\Installer\Products\c1c4f01781cc94c4c8fb1542c0981a2a"},
+; {"VS2008_x64", @"SOFTWARE\Classes\Installer\Products\67D6ECF5CD5FBA732B8B22BAC8DE1B4D"},
+; {"VS2008_x86", @"SOFTWARE\Classes\Installer\Products\6E815EB96CCE9A53884E7857C57002F0"},
+; {"VS2010_x64", @"SOFTWARE\Classes\Installer\Products\1926E8D15D0BCE53481466615F760A7F"},
+; {"VS2010_x86", @"SOFTWARE\Classes\Installer\Products\1D5E3C0FEDA1E123187686FED06E995A"},
+; {"VS2012_x64", @"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}"},
+; {"VS2012_x86", @"SOFTWARE\Classes\Installer\Dependencies\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f}"},
+; {"VS2013_x64", @"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}"},
+; {"VS2013_x86", @"SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}"},
+; {"VS2015_x64", @"SOFTWARE\Classes\Installer\Dependencies\{3ee5e5bb-b7cc-4556-8861-a00a82977d6c}"},
+; {"VS2015_x86", @"SOFTWARE\Classes\Installer\Dependencies\{23daf363-3020-4059-b3ae-dc4ad39fed19}"}
+;
+; ******************************************************************************************************************************
+[Install_VS2012]
+app1_name = Visual Studio 2012
+app1_setup_argument = /passive /norestart
+app1_reg_path = VisualStudio.DTE.11.0
+app1_reg_type = classes_root
+app1_setup_file = ..\Data\software\Visual_Studio_2012\vs_professional.exe
+
+[Install_VS2012_Update4]
+app2_name = Visual Studio 2012 - Update 4
+app2_setup_file = ..\Data\software\Visual_Studio_2012_Update_4\\VS2012.4.exe
+app2_setup_argument = /passive /norestart
+app2_reg_path = SOFTWARE\Wow6432Node\Microsoft\DevDiv\vc\Servicing\11.0\CompilerCore\1033
+app2_reg_type = local_machine
+app2_reg_value = 11.0.61030
+app2_reg_name = UpdateVersion
+app2_reg_compare = eq
+
+[Install_Sapera]
+app3_name = Sapera LT 8.11 (x64)
+app3_setup_argument = -s -f1"{app3_setup_file}\sapera_setup.iss"
+app3_setup_file = ..\Data\software\SaperaLT_Runtime_8_11\Sapera_LT_8.11_RuntimeSetup.exe
+app3_reg_display_name = Teledyne DALSA Sapera LT Runtime 8.11.00.1621 (Frame grabbers and CameraLink cameras)
+app3_reg_type = local_machine
+app3_reg_value = 8.11
+app3_reg_name = DisplayVersion
+app3_reg_compare = gte
+app3_reboot_computer_at_completion = yes
+
+[Install_PX4_Driver]
+app4_name = Xcelera-LVDS PX4 Device Driver (x64)
+app4_setup_argument = -s -f1"{app4_setup_file}\px4_setup.iss"
+app4_setup_file = ..\Data\software\TeledyneDalsa_FrameGrabber\X64_Xcelera-LVDS_PX4_1.10.01.0223.exe
+app4_reg_path = SOFTWARE\Teledyne DALSA\X64 Xcelera-LVDS PX4 Device Driver
+app4_reg_type = local_machine
+app4_reg_name = Current Version
+app4_reg_value = 1.10.01.0223
+app4_reg_compare = eq
+
+[Install_LabWindows_CVI]
+app5_name = NI LabWindows/CVI Runtime (v. 17)
+app5_setup_file = ..\Data\software\NI_LabWindows_CVI_Runtime_v17\setup.exe
+app5_setup_argument = /qb /r:n /AcceptLicenses yes
+app5_reg_display_name = NI LabWindows/CVI SxS Runtime 2017
+app5_reg_type = local_machine
+app5_reg_value = 17
+app5_reg_name = DisplayVersion
+app5_reg_compare = gte
+app5_setup_reboot_computer = yes
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used for enabling windows features
+; Only one thing needs to be defined for this section.
+; - a text file that lists windows feature name line by line
+;
+; Possible keys:
+; feature_list_file
+;
+; example:
+; windows_feature_list_file = .\feature_list.txt
+; ******************************************************************************************************************************
+[Windows_Features]
+windows_feature_list_file = .\Repository\windows_feature_list.txt
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to run various applications or scripts
+;
+; Possible keys:
+; app#_description (OPTIONAL. Describe the purpose of running this application)
+; app#_path (REQUIRED. Full path and name of the application to be run)
+; - the path can take advantage of using macros. Look below for the available macros
+; app#_is_console (REQUIRED. Specify if the application is a console application (i.e. DOS application)
+; - value is either true/false
+; app#_argument (OPTIONAL. Arguments to be passed to the application)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; - sometimes, the argument maybe include equal sign in them, but we can't have equal sign
+; in the value of the INI. To make it possible, if an equal sign is needed in the ini file
+; use in place of =
+;
+; app#_argument_path# - for each of these keys, there must be a corresponding {app#_argument_path#} defined in the value of app#_argument
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; Example 1:
+; app1_path = C:\ReleaseIB_Production\app.exe
+; app1_arguments = -role Datasrv -suite LSPS3 -production
+;
+; Example 2:
+; app1_description = Extracting ActivePerl archive
+; app1_path = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+;
+; Example 3:
+; app1_description = Extracting ActivePerl archive
+; app1_path = {cd_drive}\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+; ******************************************************************************************************************************
+[Enable_Network_Sharing]
+app3_description = Enabling Network Discovery
+app3_path = c:\windows\system32\netsh.exe
+app3_is_console = true
+app3_argument = advfirewall firewall set rule group"Network Discovery" new enableYes
+
+app4_description = Enabling File and Printer Sharing
+app4_path = c:\windows\system32\netsh.exe
+app4_is_console = true
+app4_argument = advfirewall firewall set rule group"File and Printer Sharing" new enableYes
+
+[Extract_Software_Archives]
+app1_description = Extracting Visual Studio 2012 archive
+app1_cd_label = GUTS Support Appz 1/2
+app1_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app1_is_console = true
+app1_argument = x "{cd_drive}\DISK1\msvs2012.7z" -o"{user_temp_folder}\vs2012" -y
+
+app2_description = Extracting Visual Studio 2012 Update 4 archive
+app2_cd_label = GUTS Support Appz 1/2
+app2_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app2_is_console = true
+app2_argument = x "{cd_drive}\DISK1\msvs2012_update4.7z" -o"{user_temp_folder}\vs2012_update4" -y
+
+app3_description = Extracting TeledyneDalsa archive
+app3_cd_label = GUTS Support Appz 1/2
+app3_path = {cd_drive}\DISK1\7-Zip\7z.exe
+app3_is_console = true
+app3_argument = x "{cd_drive}\DISK1\TeledyneDalsa.7z" -o"{user_temp_folder}\TeledyneDalsa" -y
+
+app4_description = Extracting NI LabWindows/CVI Runtime 2017 archive
+app4_cd_label = GUTS Support Appz 2/2
+app4_path = {cd_drive}\DISK2\7-Zip\7z.exe
+app4_is_console = true
+app4_argument = x "{cd_drive}\DISK2\NI_LabWindows_CVI_Runtime_2017.7z" -o"{user_temp_folder}\NI_LabWindows_CVI_Runtime_2017" -y
+
+[Import_Trusted_Publisher_Certificates]
+app3_description = Importing trusted publisher certificate for Teledyne DALSA
+app3_path = c:\windows\system32\certutil.exe
+app3_is_console = true
+app3_argument_path1 = ..\Data\software\TeledyneDalsa_FrameGrabber
+app3_argument = -addstore "TrustedPublisher" "{app3_argument_path1}\teledyne_dalsa_trusted_publisher.cer"
+
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Modify Network Adapter's settings
+;
+; Possible keys:
+; nic#_pci_location ( REQUIRED.)
+; - the value must be in the form of: #,#,# ( bus, device, function)
+; i.e.: 0,25,0 - bus = 0, device = 25, function = 0
+; nic#_adapter_name (OPTIONAL. Set the name of the network adapter)
+; nic#_ip_and_subnet (OPTIONAL. Set ip address and subnet mask of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,255.255.255.0
+; nic#_default_gateway# (OPTIONAL. Default gateway of the network adapter)
+; - the value must be in the form of: #.#.#.#
+; i.e.: 192.168.0.1
+; nic#_dns_servers (OPTIONAL. Set DNS servers of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,192.168.0.11
+; nic#_link_speed (OPTIONAL. Set the link speed of the network adapter)
+; - Before using this option. Make sure that the network adapter supports link speed setting
+; This is really a registry change for the network adapter. The registry name is *SpeedDuplex
+; The value for *SpeedDuplex is usually a digit ranging from 0-5.
+; Here's an example:
+; 0 - Auto Negotiate
+; 1 - 10Mbps Half Duplex
+; 2 - 10Mbps Full Duplex
+; 3 - 100Mpbs Half Duplex
+; 4 - 100Mbps Full Duplex
+; 6 - 1Gpbs Full Duplex
+; There's no 5 defined because there's no 1Gpbs Half Duplex
+; IMPORTANT: The above example was taken from a Intel network card. These numbers could
+; mean something else different from one network card to the next. Refer to the network
+; adapter's manufacturer manual for the actual numbers and their meanings.
+;
+; nic#_enable_dhcp (OPTIONAL. Set network adapter to use DHCP)
+; - the value must be either: true/false
+; - if this is set to true, all the other settings above, except link speed, will be ignored
+; this will effectively set IP and DNS Servers to be obtained automatically
+;
+; Example 1:
+; nic1_pci_location = 0,25, 0
+; nic1_link_speed = 2
+; nic1_adapter_name = My Connection
+; nic1_enable_dhcp = false
+; nic1_ip_and_subnet = 192.168.0.10 , 255.255.255.0
+; nic1_default_gateway = 192.168.0.1
+; nic1_dns_servers = 192.168.0.5, 192.168.0.6
+;
+; ******************************************************************************************************************************
+[Network_Interface_Cards]
+nic1_pci_location = 17,0,0
+nic1_adapter_name = Private_top
+nic1_ip_and_subnet = 192.168.1.3 , 255.255.255.0
+
+nic2_pci_location = 17,0,1
+nic2_adapter_name = Public_bottom
+nic2_enable_dhcp = true
+
+nic3_pci_location = 5,0,0
+nic3_adapter_name = UUT_NodeA_side_port1
+nic3_ip_and_subnet = 192.168.10.201 , 255.255.255.0
+nic3_link_speed = 3
+
+nic4_pci_location = 9,0,0
+nic4_adapter_name = UUT_NodeB_side_port2
+nic4_ip_and_subnet = 192.168.10.200 , 255.255.255.0
+nic4_link_speed = 3
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to remove/delete various files or folders
+;
+; Possible keys:
+; item (REQUIRED. This is either a file or folder to be removed)
+;
+; If the item is a folder, user has the option to specify whether or not to delete the folder recursively. To specify to delete
+; a folder recursively, add the word "recursive" right after the path separated by a comma
+;
+; The path can also include user desktop path or temporary folder
+; for desktop path, use macro: {user_desktop}
+; for temporary folder, use macro: {user_temp_folder}
+;
+; Example 1 - Delete a file:
+; item = A:\test\test.hpp
+;
+; Example 2 - Delete a folder recursively:
+; item = A:\test\test2,recursive
+;
+; Example 3 - Delete only the files contained in the folder:
+; item = A:\test\test2
+;
+; Example 4 - Delete a folder on the user's desktop:
+; item = {user_desktop}\test2
+;
+; Example 5 - Delete a folder in the user's temporary folder
+; item = {user_temp_folder}\test2
+; ******************************************************************************************************************************
+[Files_Folders_Removal]
+item = {user_temp_folder}\vs2012,recursive
+item = {user_temp_folder}\vs2012_update4,recursive
+item = {user_temp_folder}\TeledyneDalsa,recursive
+item = {user_temp_folder}\NI_LabWindows_CVI_Runtime_2017,recursive
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to copy various packages of files from a source location to destination location
+; Each XML file contains at least 1 package of files. Each file has a source and destination locations
+; Key name can be anything
+; Value must a be a path to a XML file
+;
+; example 1:
+; file_package = package1.xml
+; ******************************************************************************************************************************
+[Files_Transfer_Packages]
+file_package = ..\Data\software\Dev_PC_Software_Package.xml
+file_package = ..\Data\support_files\Dev_PC_Support_Package.xml
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Specify all the paths to be created
+; Possible keys:
+; path (REQUIRED. Valid path to be created)
+;
+; example:
+; path = C:\DataIIB\data\Block_IB\CV
+; path = C:\DataIIB\data\Block_IB\General\Logs
+; ******************************************************************************************************************************
+[Paths_Creation]
+path = D:\ReleaseIB_Production
+path = D:\ReleaseIB_Engineering
+path = D:\Data
+path = D:\Data\RealTimeTM_data
+path = D:\Development
+path = D:\ReleaseIB_Production\REAL_TIME_TM
+path = D:\ReleaseIB_Production\CorecoFrameGrabber\Video_Captures
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; To share a folder, must provide path to a folder.
+; Share names are optional as the folder name will be used as the default share name.
+; Any share name defined here will be used as additional share name for its corresponding folder
+; The # in "path#" must match in both keys. A folder can have more than one share name.
+; Possible keys:
+; path# (OPTIONAL. A valid path to be shared)
+; path#_additional_share_names (OPTIONAL. Additional share names associated with a path)
+; - Define one or more shares names separated by comma
+; path#_allowed_accounts ( Windows Built-In, local or domain accounts to be added to the permission list for this share with Full Control )
+; - if this is not defined, this network share will be accessible to everyone with Full Control
+; - if defined, the value must be in the following format:
+; User1,User2,User3 (if more than one account is defined, separate by comma)
+; The account name must either be a built-in window account or local/domain account
+; if the account name is a built-in window account, it can only be one of the following:
+; - everyone, authenticated users
+; if the account name is a local/domain account it must be in this format: DOMAIN\UserAccountName
+;
+; example:
+; path1 = C:\DataIIB\
+; path1_additional_share_names = DataIIB1, DataIIB2
+; path1_allowed_accounts = Authenticated Users,US\1117637
+; path2 = C:\DataIA
+; path2__additional_share_names = DataIA_1
+; path2_allowed_accounts = MYCOMPUTERNAME\Duc
+; path3 = C:\DataIC
+; ******************************************************************************************************************************
+[Paths_Sharing]
+path1 = D:\ReleaseIB_Production\
+path1_allowed_accounts = Authenticated Users
+
+path2 = D:\ReleaseIB_Engineering\
+path2_allowed_accounts = Authenticated Users
+
+path3 = D:\Data\
+path3_allowed_accounts = Authenticated Users
+
+path4 = D:\Development\
+path4_allowed_accounts = Authenticated Users
+
+path5 = D:\ReleaseIB_Production\REAL_TIME_TM
+path5_allowed_accounts = Authenticated Users
+
+path6 = C:\
+path6_allowed_accounts = Authenticated Users
+
+path7 = D:\
+path7_allowed_accounts = Authenticated Users
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create windows system environment variables
+; the key would be the system environment variable name.
+;
+; Note:
+; Any key defined here will have its valued replaced, except for "path" because path is a window's system environment variable
+; If a key's name is path, the value specified will be appendeding to existing value
+;
+; path can have one or more values separated by commas
+; Example:
+; path = C:\folder1
+; path = C:\folder1, C:\folder2
+; ******************************************************************************************************************************
+[Env_Variables]
+;SM3_SEEKER = C:\Development\GUTS\SM3
+; the address of the computer where all the data of each test is saved before being pushed to the network
+;SM3_SKR_SERVER = localhost
+; the address of the computer where all test data are pushed to after testing
+;SM3_SKR_NETWORK = localhost
+;path = C:\Perl\bin\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Add/Modify or Delete registry's key
+;
+; Possible keys:
+; reg#_action ( REQUIRED. What action to perform)
+; - there are only 2 actions ( add/modify, delete)
+; reg#_path (REQUIRED. Registry folder path, not including valuename)
+; reg#_type (REQUIRED)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; reg#_name_value_pair# (Optional. Registry name values and their names)
+; - the registry key defined by registry path can have multiple value names and their associated values
+; - Format of the value: [name:***,value:***,type:***] - replace *** with actual text
+; - name can be anything
+; - value is either numeric or alphanumeric depending on type
+; - type can only be 1 of 4: string, multi-string, dword, qword
+; If type is dword or qword then value can only be numeric
+; If type is multi-string, then format of the value must be:
+; [name:***,:value:***:value:***...,type:multi-string]
+;
+; Example 1:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\MySoftware\
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version,value:3,type:string]
+; reg1_name_value_pair2 = [name:Version2,:value:3:value:34,type:multi-string]
+;
+; Example 2:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+;
+; Example3:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version]
+;
+; Example4:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; ******************************************************************************************************************************
+[Windows_Registry]
+reg1_action = add/modify
+reg1_path = SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
+reg1_type = local_machine
+reg1_name_value_pair1 = [name:BackConnectionHostNames,:value:ste_gu_dev_local,type:multi_string]
+
+reg2_action = add/modify
+reg2_path = SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters
+reg2_type = local_machine
+reg2_name_value_pair1 = [name:DisableStrictNameChecking,value:1,type:dword]
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create shortcuts on the user's desktop
+;
+; example:
+; shortcut1_name = Data Server
+; shortcut1_target_path = C:\ReleaseIB_Production\app.exe
+; shortcut1_arguments = -role datasrv -suite lsps3 -production
+; ******************************************************************************************************************************
+[Windows_Shortcuts]
+shortcut1_name = CorecoFrameGrabber
+shortcut1_target_path = D:\ReleaseIB_Production\CorecoFrameGrabber\CorecoFrameGrabber.exe
+shortcut1_for_all_users = true
+
+shortcut2_name = RealTime TM
+shortcut2_target_path = D:\ReleaseIB_Production\REAL_TIME_TM\RealTimeTm.exe
+shortcut2_for_all_users = true
+
+shortcut3_name = ASP Diagnostics GUI
+shortcut3_target_path = D:\ReleaseIB_Production\ASP Diagnostics GUI\diag_64.exe
+shortcut3_for_all_users = true
+
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_engineering.ini b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_engineering.ini
new file mode 100644
index 0000000..1dff77c
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/Config_Files/config_engineering.ini
@@ -0,0 +1,636 @@
+; ************************************************* SM3 CONFIGURATION FILE *****************************************************
+; Description:
+; This is an INI file which contains the configuration information for the automated setup of either an
+; ENGINEERING or PRODUCTION environment for developing or running SM3 GUTS (Guidance Unit Test Software)
+;
+; Author: Duc Le
+;
+; ******************************************************************************************************************************
+;
+;
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+[General]
+Program_Name = SM3 Block IB - Engineering Setup
+; 64-bit or 32-bit. Possible values: 32 or 64
+Application_Platform = 32
+
+[Global_Settings]
+Always_Run_Application_Using_Admin_Account = true
+Suppress_All_Prompts = true
+Provide_Windows_Password_For_Auto_Login = false
+
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+; This section defines all the setup steps to be performed and allow the user the option of enabling/disabling each step
+; The key can be anything.
+; The value must define the setup step and its associated section name separated by comma: Setup_Step,Section_Name
+; Below is a list of all possible setup steps:
+; CONFIGURE_NETWORK_ADAPTERS
+; RUN_APPLICATIONS
+; INSTALL_SOFTWARE_PACKAGES
+; ENABLE_INTERNET_INFORMATION_SERVICES
+; CREATE_DIRECTORIES
+; CREATE_NETWORK_SHARES
+; SET_ENVIRONMENT_VARIABLES
+; SET_DOTNET_FRAMEWORK_2_SECURITY_ZONE_LEVELS
+; TRANSFER_FILE_PACKAGES
+; MODIFY_WINDOWS_REGISTRY
+; PROCESS_GUTS_CONFIG_FILE
+; CREATE_WINDOWS_SHORTCUTS
+; ASSIST_BUILDING_GUTS_APP
+; REMOVE_FILES_FOLDERS
+;
+; The setup setup can be run more than once by creating another key and assigned the setup step to it
+; Each setup step needs a section name. Section name provides all the information necessary for the setup step
+; The sequence of the execution of the setup steps will be in the same order as they are specified.
+; ******************************************************************************************************************************
+[Setup_Step_Manager]
+;step = RUN_APPLICATIONS,Extract_Software_Archives
+step = INSTALL_SOFTWARE_PACKAGES,Install_Software
+step = CREATE_DIRECTORIES,Paths_Creation
+step = CREATE_NETWORK_SHARES,Paths_Sharing
+step = SET_ENVIRONMENT_VARIABLES,Env_Variables
+step = TRANSFER_FILE_PACKAGES,Files_Transfer_Packages
+step = CREATE_WINDOWS_SHORTCUTS,Windows_Shortcuts
+;step = RUN_APPLICATIONS,Shut_Down_National_Instruments_Processes
+;step = REMOVE_FILES_FOLDERS , Files_Folders_Removal
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to install various software application
+; For each software application to be installed, 4 things can be defined:
+;
+; Possible keys:
+; app#_name (REQUIRED. Name of the application to be installed/checked)
+; app#_setup_file (OPTIONAL. Path and name of the installer)
+; - the setup file can make use of macros. Look below for the available macros
+; app#_setup_argument (OPTIONAL. Argument for the setup file. Usually to perform unattended install)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; app#_setup_confirm_prompt (OPTIONAL. Prompt user to confirm before installation starts.)
+; - possible values: yes, no
+; - yes: there will be prompt asking user confirm/refuse install
+; - no: installation will start automatically ( this is the default )
+; app#_exe_file (REQUIRED only if app#_hklm_reg_key is not specified.
+; This is used to verify that the software successfully installed)
+; app#_reg_path (REQUIRED only if app#_exe_file is not specified. Registry folder path, not including valuename)
+; app#_reg_type (REQUIRED only if app#_reg_key is specified)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; app#_reg_value (REQUIRED only if app#_reg_key is specified. Registry value name's value)
+; app#_reg_name (REQUIRED only if app#_reg_key is specified. Registry value name)
+; app#_reg_compare (REQUIRED only if app#_reg_key is specified. Compare operator between value name's value specified here versus actual value read from registry)
+; - there are only six options for this key ( eq, lt, gt, lte, gte, ne )
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; example 1:
+; app1_name = Perl 5.6.1.638
+; app1_setup_file = {user_temp_folder}\Installer.bat
+; app1_exe_file = C:\Perl\bin\perl.exe
+;
+; example 2:
+; app1_reg_path = SOFTWARE\National Instruments\NI-488.2\CurrentVersion
+; app1_reg_type = local_machine
+; app1_reg_value = 15.0
+; app1_reg_name = Version
+; app1_reg_compare = gte
+; app1_name = National Instrument 488.2 (v15 or higher)
+; app1_setup_file = C:\ni\setup.exe
+;
+; example 3:
+; app1_exe_file = C:\Perl\bin\perl.exe
+; app1_name = Perl 5.6.1.638
+;
+; example 4:
+; app1_name = Sapera LT 8.11 (x64)
+; app1_setup_file = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\Software\TeledyneDalsa\Sapera_LT_8.11_RuntimeSetup.exe
+; app1_setup_argument = -s -f1"{app1_setup_file}\sapera_setup.iss"
+; app1_reg_path = SOFTWARE\Teledyne DALSA\Sapera LT
+; app1_reg_type = local_machine
+; app1_reg_name = IsSaperaFrameGrabberSupport
+;
+; ******************************************************************************************************************************
+; Visual Studio ClassRoot Registry Keys
+;
+; {"VS2005", "VisualStudio.DTE.8.0"},
+; {"VS2008", "VisualStudio.DTE.9.0"},
+; {"VS2010", "VisualStudio.DTE.10.0"},
+; {"VS2012", "VisualStudio.DTE.11.0"},
+; {"VS2013", "VisualStudio.DTE.12.0"},
+; {"VS2015", "VisualStudio.DTE.13.0"}
+;
+; Visual Studio Redistributable Local_Machine Registry Keys
+;
+; {"VS2005_x64", @"SOFTWARE\Classes\Installer\Products\1af2a8da7e60d0b429d7e6453b3d0182"},
+; {"VS2005_x86", @"SOFTWARE\Classes\Installer\Products\c1c4f01781cc94c4c8fb1542c0981a2a"},
+; {"VS2008_x64", @"SOFTWARE\Classes\Installer\Products\67D6ECF5CD5FBA732B8B22BAC8DE1B4D"},
+; {"VS2008_x86", @"SOFTWARE\Classes\Installer\Products\6E815EB96CCE9A53884E7857C57002F0"},
+; {"VS2010_x64", @"SOFTWARE\Classes\Installer\Products\1926E8D15D0BCE53481466615F760A7F"},
+; {"VS2010_x86", @"SOFTWARE\Classes\Installer\Products\1D5E3C0FEDA1E123187686FED06E995A"},
+; {"VS2012_x64", @"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}"},
+; {"VS2012_x86", @"SOFTWARE\Classes\Installer\Dependencies\{33d1fd90-4274-48a1-9bc1-97e33d9c2d6f}"},
+; {"VS2013_x64", @"SOFTWARE\Classes\Installer\Dependencies\{050d4fc8-5d48-4b8f-8972-47c82c46020f}"},
+; {"VS2013_x86", @"SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}"},
+; {"VS2015_x64", @"SOFTWARE\Classes\Installer\Dependencies\{3ee5e5bb-b7cc-4556-8861-a00a82977d6c}"},
+; {"VS2015_x86", @"SOFTWARE\Classes\Installer\Dependencies\{23daf363-3020-4059-b3ae-dc4ad39fed19}"}
+;
+; ******************************************************************************************************************************
+[Install_Software]
+app5_name = Visual Studio 2012
+app5_setup_argument = /passive /norestart
+app5_reg_path = VisualStudio.DTE.11.0
+app5_reg_type = classes_root
+app5_setup_file = ..\Data\software\Visual_Studio_2012\vs_professional.exe
+
+app6_name = Visual Studio 2012 - Update 4
+app6_setup_file = ..\Data\software\Visual_Studio_2012_Update_4\VS2012.4.exe
+app6_setup_argument = /passive /norestart
+app6_reg_path = SOFTWARE\Wow6432Node\Microsoft\DevDiv\vc\Servicing\11.0\CompilerCore\1033
+app6_reg_type = local_machine
+app6_reg_value = 11.0.61030
+app6_reg_name = UpdateVersion
+app6_reg_compare = eq
+
+app2_name = National Instrument 488.2 (ver. 17)
+app2_setup_file = ..\Data\software\NI_4882_v17\setup.exe
+app2_setup_argument = /qb /r:n /AcceptLicenses yes
+app2_reg_display_name = NI-488.2 17.0
+app2_reg_type = local_machine
+app2_reg_value = 17
+app2_reg_name = DisplayVersion
+app2_reg_compare = gte
+app2_reboot_computer_at_completion = yes
+app2_exit_codes_to_ignore = 3010
+
+app3_name = National Instrument VXI (ver. 16)
+app3_setup_file = ..\Data\software\NI_VXI_v17\setup.exe
+app3_setup_argument = /qb /r:n /AcceptLicenses yes
+app3_reg_display_name = NI-VXI 16.0
+app3_reg_type = local_machine
+app3_reg_value = 16
+app3_reg_name = DisplayVersion
+app3_reg_compare = gte
+app3_reboot_computer_at_completion = yes
+app3_exit_codes_to_ignore = 3010
+
+app7_name = Sapera LT 8.11 (x64)
+app7_setup_argument = -s -f1"{app7_setup_file}\sapera_setup.iss"
+app7_setup_file = ..\Data\software\TeledyneDalsa_FrameGrabber\Sapera_LT_8.11_RuntimeSetup.exe
+app7_reg_display_name = Teledyne DALSA Sapera LT Runtime 8.11.00.1621 (Frame grabbers and CameraLink cameras)
+app7_reg_type = local_machine
+app7_reg_value = 8.11
+app7_reg_name = DisplayVersion
+app7_reg_compare = gte
+app7_reboot_computer_at_completion = yes
+
+;app1_setup_confirm_prompt = yes
+app1_name = ActivePerl 5.6.1.638
+app1_setup_file = ..\Data\software\Perl_5_6\Installer_Silent.bat
+app1_exe_file = C:\Perl\bin\perl.exe
+
+app4_name = Visual Studio Redistributable 2013 (x86)
+app4_setup_file = ..\Data\software\VS2013_Redistributable\vcredist_x86.EXE
+app4_setup_argument = /install /passive /norestart
+app4_reg_path = SOFTWARE\Classes\Installer\Dependencies\{f65db027-aff3-4070-886a-0d87064aabb1}
+app4_reg_type = local_machine
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used for enabling windows features
+; Only one thing needs to be defined for this section.
+; - a text file that lists windows feature name line by line
+;
+; Possible keys:
+; feature_list_file
+;
+; example:
+; windows_feature_list_file = .\feature_list.txt
+; ******************************************************************************************************************************
+[Windows_Features]
+windows_feature_list_file = ..\Data\windows_feature_list.txt
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to run various applications or scripts
+;
+; Possible keys:
+; app#_description (OPTIONAL. Describe the purpose of running this application)
+; app#_path (REQUIRED. Full path and name of the application to be run)
+; - the path can take advantage of using macros. Look below for the available macros
+; app#_is_console (REQUIRED. Specify if the application is a console application (i.e. DOS application)
+; - value is either true/false
+; app#_argument (OPTIONAL. Arguments to be passed to the application)
+; - sometimes the argument can include paths. Some programs will require absolute path while others allow relative paths
+; the user has the option of specifying relative paths in the argument and have the program resolve them at runtime
+; In order to make this possible, the user will have to specify a new key for each path to be resolved in the argument
+; - the argument can specify {app#_path}
+; - the argument can make use of macros. Look below for the available macros
+; - the actual path being inserted in the argument will not have backslash at the end of the path
+; - sometimes, the argument maybe include equal sign in them, but we can't have equal sign
+; in the value of the INI. To make it possible, if an equal sign is needed in the ini file
+; use in place of =
+;
+; app#_argument_path# - for each of these keys, there must be a corresponding {app#_argument_path#} defined in the value of app#_argument
+;
+; Available Path macros:
+; {user_desktop}, {user_temp_folder}, {cd_drive}
+;
+; Example 1:
+; app1_path = C:\ReleaseIB_Production\app.exe
+; app1_arguments = -role Datasrv -suite LSPS3 -production
+;
+; Example 2:
+; app1_description = Extracting ActivePerl archive
+; app1_path = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+;
+; Example 3:
+; app1_description = Extracting ActivePerl archive
+; app1_path = {cd_drive}\7-Zip\7z.exe
+; app1_argument_path1 = ..\..\..\..\..\Deployment\SM3_IB_Auto_Setup\Repository\software\
+; app1_argument = x "{app1_argument_path1}\Perl.7z" -o"{user_temp_folder}" -y
+; ******************************************************************************************************************************
+[Extract_Software_Archives]
+;app1_description = Extracting Visual Studio 2012 archive
+;app1_cd_label = GUTS Support Appz 1/2
+;app1_path = {cd_drive}\DISK1\7-Zip\7z.exe
+;app1_is_console = true
+;app1_argument = x "{cd_drive}\DISK1\msvs2012.7z" -o"{user_temp_folder}\vs2012" -y
+
+;app2_description = Extracting Visual Studio 2012 Update 4 archive
+;app2_cd_label = GUTS Support Appz 1/2
+;app2_path = {cd_drive}\DISK1\7-Zip\7z.exe
+;app2_is_console = true
+;app2_argument = x "{cd_drive}\DISK1\msvs2012_update4.7z" -o"{user_temp_folder}\vs2012_update4" -y
+
+app3_description = Extracting NI 488.2 v17 archive
+app3_cd_label = GUTS Support Appz 1/2
+app3_path = E:\Duc\IB_Appz\DISK1\7-Zip\7z.exe
+app3_is_console = true
+app3_argument = x "E:\Duc\IB_Appz\DISK1\NI_4882_v17.7z" -o"{user_temp_folder}" -y
+
+app4_description = Extracting NI VXI v16 archive
+app4_cd_label = GUTS Support Appz 1/2
+app4_path = E:\Duc\IB_Appz\DISK1\7-Zip\7z.exe
+app4_is_console = true
+app4_argument = x "E:\Duc\IB_Appz\DISK1\NI_VXI_v17.7z" -o"{user_temp_folder}" -y
+
+app5_description = Extracting ActivePerl 5.6 archive
+app5_cd_label = GUTS Support Appz 1/2
+app5_path = E:\Duc\IB_Appz\DISK1\7-Zip\7z.exe
+app5_is_console = true
+app5_argument = x "E:\Duc\IB_Appz\DISK1\Perl_5_6.7z" -o"{user_temp_folder}" -y
+
+app6_description = Extracting Teledyne Dalsa SaperaLT Runtime 8.11 archive
+app6_cd_label = GUTS Support Appz 1/2
+app6_path = E:\Duc\IB_Appz\DISK1\7-Zip\7z.exe
+app6_is_console = true
+app6_argument = x "E:\Duc\IB_Appz\DISK1\SaperaLT_Runtime_8_11.7z" -o"{user_temp_folder}" -y
+
+[Shut_Down_National_Instruments_Processes]
+app1_description = Killing process nierserver.exe
+app1_path = C:\Windows\system32\taskkill.exe
+app1_is_console = true
+app1_argument = /f /im nierserver.exe
+
+;
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Modify Network Adapter's settings
+;
+; Possible keys:
+; nic#_pci_location ( REQUIRED.)
+; - the value must be in the form of: #,#,# ( bus, device, function)
+; i.e.: 0,25,0 - bus = 0, device = 25, function = 0
+; nic#_adapter_name (OPTIONAL. Set the name of the network adapter)
+; nic#_ip_and_subnet (OPTIONAL. Set ip address and subnet mask of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,255.255.255.0
+; nic#_default_gateway# (OPTIONAL. Default gateway of the network adapter)
+; - the value must be in the form of: #.#.#.#
+; i.e.: 192.168.0.1
+; nic#_dns_servers (OPTIONAL. Set DNS servers of network adapter)
+; - the value must be in the form of: #.#.#.#,#.#.#.#
+; i.e.: 192.168.0.10,192.168.0.11
+; nic#_link_speed (OPTIONAL. Set the link speed of the network adapter)
+; - Before using this option. Make sure that the network adapter supports link speed setting
+; This is really a registry change for the network adapter. The registry name is *SpeedDuplex
+; The value for *SpeedDuplex is usually a digit ranging from 0-5.
+; Here's an example:
+; 0 - Auto Negotiate
+; 1 - 10Mbps Half Duplex
+; 2 - 10Mbps Full Duplex
+; 3 - 100Mpbs Half Duplex
+; 4 - 100Mbps Full Duplex
+; 6 - 1Gpbs Full Duplex
+; There's no 5 defined because there's no 1Gpbs Half Duplex
+; IMPORTANT: The above example was taken from a Intel network card. These numbers could
+; mean something else different from one network card to the next. Refer to the network
+; adapter's manufacturer manual for the actual numbers and their meanings.
+;
+; nic#_enable_dhcp (OPTIONAL. Set network adapter to use DHCP)
+; - the value must be either: true/false
+; - if this is set to true, all the other settings above, except link speed, will be ignored
+; this will effectively set IP and DNS Servers to be obtained automatically
+;
+; Example 1:
+; nic1_pci_location = 0,25, 0
+; nic1_link_speed = 2
+; nic1_adapter_name = My Connection
+; nic1_enable_dhcp = false
+; nic1_ip_and_subnet = 192.168.0.10 , 255.255.255.0
+; nic1_default_gateway = 192.168.0.1
+; nic1_dns_servers = 192.168.0.5, 192.168.0.6
+;
+; ******************************************************************************************************************************
+[Network_Interface_Cards]
+
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to remove/delete various files or folders
+;
+; Possible keys:
+; item (REQUIRED. This is either a file or folder to be removed)
+;
+; If the item is a folder, user has the option to specify whether or not to delete the folder recursively. To specify to delete
+; a folder recursively, add the word "recursive" right after the path separated by a comma
+;
+; The path can also include user desktop path or temporary folder
+; for desktop path, use macro: {user_desktop}
+; for temporary folder, use macro: {user_temp_folder}
+;
+; Example 1 - Delete a file:
+; item = A:\test\test.hpp
+;
+; Example 2 - Delete a folder recursively:
+; item = A:\test\test2,recursive
+;
+; Example 3 - Delete only the files contained in the folder:
+; item = A:\test\test2
+;
+; Example 4 - Delete a folder on the user's desktop:
+; item = {user_desktop}\test2
+;
+; Example 5 - Delete a folder in the user's temporary folder
+; item = {user_temp_folder}\test2
+; ******************************************************************************************************************************
+[Files_Folders_Removal]
+item = {user_temp_folder}\Perl_5_6,recursive
+item = {user_temp_folder}\vs2012,recursive
+item = {user_temp_folder}\vs2012_update4,recursive
+item = {user_temp_folder}\NI_4882_v17,recursive
+item = {user_temp_folder}\NI_VXI_v17,recursive
+item = {user_temp_folder}\SaperaLT_Runtime_8_11,recursive
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is used to copy various packages of files from a source location to destination location
+; Each XML file contains at least 1 package of files. Each file has a source and destination locations
+; Key name can be anything
+; Value must a be a path to a XML file
+;
+; example 1:
+; file_package = package1.xml
+; ******************************************************************************************************************************
+[Files_Transfer_Packages]
+file_package = ..\Data\software\Engineering_PC_Software_Package.xml
+file_package = ..\Data\support_files\Engineering_PC_Support_Package.xml
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Specify all the paths to be created
+; Possible keys:
+; path (REQUIRED. Valid path to be created)
+;
+; example:
+; path1 = C:\DataIIB\data\Block_IB\CV
+; path2 = C:\DataIIB\data\Block_IB\General\Logs
+; ******************************************************************************************************************************
+[Paths_Creation]
+path = C:\ReleaseIB_Engineering\
+path = C:\ReleaseIB_Production\
+path = C:\DataIB\data\Block_IB\CV
+path = C:\DataIB\data\Block_IB\General\Logs
+path = C:\DataIB\data\Block_IB\General\Scripts
+path = C:\DataIB\data\Block_IB\General\Temp\SingleStepScript
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; To share a folder, must provide path to a folder.
+; Share names are optional as the folder name will be used as the default share name.
+; Any share name defined here will be used as additional share name for its corresponding folder
+; The # in "path#" must match in both keys. A folder can have more than one share name.
+; Possible keys:
+; path# (OPTIONAL. A valid path to be shared)
+; path#_additional_share_names (OPTIONAL. Additional share names associated with a path)
+; - Define one or more shares names separated by comma
+; path#_allowed_accounts ( Windows Built-In, local or domain accounts to be added to the permission list for this share with Full Control )
+; - if this is not defined, this network share will be accessible to everyone with Full Control
+; - if defined, the value must be in the following format:
+; User1,User2,User3 (if more than one account is defined, separate by comma)
+; The account name must either be a built-in window account or local/domain account
+; if the account name is a built-in window account, it can only be one of the following:
+; - everyone, authenticated users
+; if the account name is a local/domain account it must be in this format: DOMAIN\UserAccountName
+;
+; example:
+; path1 = C:\DataIIB\
+; path1_additional_share_names = DataIIB1, DataIIB2
+; path1_allowed_accounts = Authenticated Users,US\1117637
+; path2 = C:\DataIA
+; path2__additional_share_names = DataIA_1
+; path2_allowed_accounts = MYCOMPUTERNAME\Duc
+; path3 = C:\DataIC
+; ******************************************************************************************************************************
+[Paths_Sharing]
+path1 = C:\ReleaseIB_Engineering\
+path2_additional_share_names = Data
+path2 = C:\DataIB\
+path3_additional_share_names = Release
+path3 = C:\ReleaseIB_Production\
+
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create windows system environment variables
+; the key would be the system environment variable name.
+;
+; Note:
+; Any key defined here will have its valued replaced, except for "path" because path is a window's system environment variable
+; If a key's name is path, the value specified will be appendeding to existing value
+;
+; path can have one or more values separated by commas
+; Example:
+; path = C:\folder1
+; path = C:\folder1, C:\folder2
+; ******************************************************************************************************************************
+[Env_Variables]
+SM3_SEEKER = C:\Development\GUTS\SM3
+; the address of the computer where all the data of each test is saved before being pushed to the network
+SM3_SKR_SERVER = localhost
+; the address of the computer where all test data are pushed to after testing
+SM3_SKR_NETWORK = localhost
+path = C:\Perl\bin\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Add/Modify or Delete registry's key
+;
+; Possible keys:
+; reg#_action ( REQUIRED. What action to perform)
+; - there are only 2 actions ( add/modify, delete)
+; reg#_path (REQUIRED. Registry folder path, not including valuename)
+; reg#_type (REQUIRED)
+; - there are only three options for this key ( classes_root, current_user, local_machine)
+; reg#_name_value_pair# (Optional. Registry name values and their names)
+; - the registry key defined by registry path can have multiple value names and their associated values
+; - Format of the value: [name:***,value:***,type:***] - replace *** with actual text
+; - name can be anything
+; - value is either numeric or alphanumeric depending on type
+; - type can only be 1 of 4: string, multi_string, dword, qword
+; If type is dword or qword then value can only be numeric
+; If type is multi-string, then format of the value must be:
+; [name:***,:value:***:value:***...,type:multi_string]
+;
+; Example 1:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\MySoftware\
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version,value:3,type:string]
+; reg1_name_value_pair2 = [name:Version2,:value:3:value:34,type:multi-string]
+;
+; Example 2:
+; reg1_action = add/modify
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+;
+; Example3:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; reg1_name_value_pair1 = [name:Version]
+;
+; Example4:
+; reg1_action = delete
+; reg1_path = SOFTWARE\Duc\Sup
+; reg1_type = local_machine
+; ******************************************************************************************************************************
+[Windows_Registry]
+;reg1_action = delete
+;reg1_path = SOFTWARE\Duc\
+;reg1_type = local_machine
+;reg1_name_value_pairs = Versionn[:]3[,]ginrl[:]boy
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Create shortcuts on the user's desktop
+;
+; example:
+; shortcut1_name = Data Server
+; shortcut1_target_path = C:\ReleaseIB_Production\app.exe
+; shortcut1_arguments = -role datasrv -suite lsps3 -production
+; ******************************************************************************************************************************
+[Windows_Shortcuts]
+shortcut1_name = GUTS Startup - Dev
+shortcut1_target_path = C:\Perl\bin\perl.exe
+shortcut1_arguments = C:\ReleaseIB_Production\Utils\guts_startup_dev.pl
+
+shortcut2_name = CorecoFramegrabber
+shortcut2_target_path = C:\ReleaseIB_Production\CorecoFrameGrabber\CorecoFrameGrabber.exe
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; Before building GUTS, the dashboard.pl must be executed to copy additional files to the GUTS project folder
+; Before dashboard.pl can be run, 2 environment variables must be set:
+; 1. Path to the GUTS development folder - this is where the script know to put the files in
+; 2. Path to the Perl executable
+; Possible keys:
+; GUTS_Development_Folder - (REQUIRED. The path to where the GUTS Project is located)
+; list_of_additional_files (REQUIRED. The full path and name of file that contains a complete list of files to be added by the dashboard.pl)
+; perl_binary_path (REQUIRED. Path to where the perl executable is. This is necessary to run perl scripts)
+;
+; example:
+; ******************************************************************************************************************************
+[GUTS_Pre_Build_Assistance]
+GUTS_Development_Folder = C:\GUTS_31202_VS2012_Synergy_PostScriptRun1\GUTS\SM3
+list_of_additional_files = ..\..\..\..\GUTS\list_of_guts_additional_files.txt
+perl_binary_path = C:\Perl\bin\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS REQUIRED
+; ******************************************************************************************************************************
+; This section is mainly to configure the GUTS config file's settings and renaming to the right name for the GUTS app to use
+; ******************************************************************************************************************************
+[GUTS_Info]
+sm3seeker_config_file = .\Repository\support_files\All\sm3seeker.cfg
+; folder where GUTS app and DLLs are located and run from
+Guts_Bin_Dir = C:\ReleaseIB_Production\
+
+; ******************************************************************************************************************************
+; THIS SECTION IS OPTIONAL
+; ******************************************************************************************************************************
+; This section is responsible for changing the values of the keys in the GUTS Config File.
+; The GUTS config file name and location are determined by the various settings in section [GUTS_Info], therefore there's no need to
+; specify what and where the file is located at. It should be in the GUTS Bin directory and named according to the hardware
+; type that is defined in section [GUTS_Info].
+;
+; Key Format: Can be anything
+; Value Format: the value should have a [,] as a delimiter between the Section, Key and Value in the GUTS' Config File
+;
+; Example:
+; Setting = General[,]DATA_SRV_ADDR[,]localhost
+; General - section name in the GUTS Config File
+; DATA_SRV_ADDR - the key in the section in the GUTS Config File
+; localhost - value associated with the key
+;
+; ******************************************************************************************************************************
+[GUTS_Config_File]
+; IP address of the GUTS Data Server
+Setting = General[,]DATA_SRV_ADDR[,]localhost
+
+; IP address of the GUTS Server
+Setting = General[,]GUTS_SRV_ADDR[,]localhost
+
+; IP address of the GUTS GUOT Server
+Setting = General[,]GUTS_GUOT_SRV_ADDR[,]localhost
+
+; IP address of the Coreco Framegrabber Server
+Setting = General[,]CORECO_FRAMEGRABBER_SRV_ADDR[,]localhost
+
+; IP address of the Acroamatics server
+Setting = General[,]TM_DECOM_ADDR[,]localhost
+
+; IP address of the wideband server
+Setting = General[,]TM_DDR100_ADDR[,]localhost
+
+; IP address of the LSPS controller server
+Setting = General[,]LSPS_ADDR[,]localhost
+
+; IP address of the vendor's guot server
+Setting = UUT_CONTROLLER[,]VENDOR_GUOT_SRV_ADDR[,]localhost
+
+Setting = OPTICS[,]WAVELENGTH[,]2.2
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/Control_PC_Software_Package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/Control_PC_Software_Package.xml
new file mode 100644
index 0000000..a9a1bec
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/Control_PC_Software_Package.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/Control_PC_Support_Package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/Control_PC_Support_Package.xml
new file mode 100644
index 0000000..921a3e9
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/Control_PC_Support_Package.xml
@@ -0,0 +1,134 @@
+
+
+
+
+
+ PathLossLog.txt
+
+
+ DaqSetup.dat
+
+
+ SecretTlmMsg.dll
+
+
+ Sm3Seeker.cfg
+
+
+ startup.pl
+
+
+ startupConfig.ini
+
+
+ WidebandAccount.bat
+
+
+
+
+ hosts
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/Dev_PC_Software_Package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/Dev_PC_Software_Package.xml
new file mode 100644
index 0000000..0d3e85e
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/Dev_PC_Software_Package.xml
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/Dev_PC_Support_package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/Dev_PC_Support_package.xml
new file mode 100644
index 0000000..d7b8cbe
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/Dev_PC_Support_package.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+ Grabber.cfg
+
+
+ *.*
+
+
+
+
+ hosts
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/Engineering_PC_Software_Package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/Engineering_PC_Software_Package.xml
new file mode 100644
index 0000000..12bf9bc
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/Engineering_PC_Software_Package.xml
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/Engineering_PC_Support_Package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/Engineering_PC_Support_Package.xml
new file mode 100644
index 0000000..35482f5
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/Engineering_PC_Support_Package.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+ PathLossLog.txt
+
+
+ guts_startup_dev.pl
+ guts_startup.ini
+
+
+ Sm3Seeker.cfg
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/NGI_CTS_File_Package.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/NGI_CTS_File_Package.xml
new file mode 100644
index 0000000..12d53db
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/NGI_CTS_File_Package.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+ nuget.config
+
+
+
+
+ *.nupkg
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/Important_Files/Examples/XML/PackagesFromCD.xml b/AllPurposeAutoSetup/Important_Files/Examples/XML/PackagesFromCD.xml
new file mode 100644
index 0000000..4d28d46
--- /dev/null
+++ b/AllPurposeAutoSetup/Important_Files/Examples/XML/PackagesFromCD.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ MK698Software.7z.001
+
+
+ MK698Software.7z.002
+
+
+
\ No newline at end of file
diff --git a/AllPurposeAutoSetup/NetworkAdapterManager.cs b/AllPurposeAutoSetup/NetworkAdapterManager.cs
new file mode 100644
index 0000000..89b3618
--- /dev/null
+++ b/AllPurposeAutoSetup/NetworkAdapterManager.cs
@@ -0,0 +1,746 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+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 CommonLib.Windows.Forms;
+using CommonLib.Windows.Misc;
+using CommonLib.IO;
+using CommonLib.Misc;
+
+namespace All_Purpose_Auto_Setup
+{
+ class NetworkAdapterManager
+ {
+ // An event that can be raised, allowing other classes to
+ // subscribe to it and do what they like with the message.
+ public event Action> UpdateStatusDisplayAndLogEvent;
+
+ // this dictionary stores the application to be executed and the arguments associated with it
+ // it would look like this:
+ // [ c:\app1.exe ] -> [path arg arg_path]
+ // [ c:\app2.exe ] -> [path arg arg_path]
+ public Dictionary, List>> networkAdapterPciLocationToVarious = new Dictionary, List>>();
+
+ // event for thread to notify other threads that it has exited
+ private AutoResetEvent _resetEvent = new AutoResetEvent(false);
+
+ Form m_parentForm;
+
+ public NetworkAdapterManager(Form parentForm)
+ {
+ m_parentForm = parentForm;
+ }
+
+ public bool configureNetworkAdapters(string sectionName)
+ {
+ bool setupSuccessful = true;
+ string msg = "", msg2 = "", indentation = String.Empty, errMsg = "";
+
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor defaultTextProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ CommonLib.Windows.Forms.TextFormat.TextFontAndColor textProp = new CommonLib.Windows.Forms.TextFormat.TextFontAndColor("");
+ List textPropList = new List();
+ List textPropList2 = new List();
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 100;
+ textPropList.Add(textProp);
+
+ DateTime dat1 = DateTime.Now;
+ msg = "\n\n<-------------------Date and Time: " + dat1.ToString(@"MM/dd/yyyy hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture) + "------------------->";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStepTitleColor();
+ textProp.wordIndex = 0;
+ textProp.wordCount = 10;
+ // set font size
+ textProp.textFont = new Font(textProp.textFont.Name, 12);
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ msg = "\n-=Configuring Network Adapters=-";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+
+ networkAdapterPciLocationToVarious.Clear();
+
+ ConfigFileManager.readOneToManyDictionary(ConfigFileManager.ms_configGeneralInfo.iniFile,
+ sectionName, @"(nic\d+)_pci_location$", @"(nic\d+)_.+$", networkAdapterPciLocationToVarious);
+
+ setupSuccessful = verifyConfigInfo();
+
+ if (setupSuccessful)
+ {
+ if (networkAdapterPciLocationToVarious.Count == 0 ||
+ (networkAdapterPciLocationToVarious.Count == 1 && networkAdapterPciLocationToVarious.First().Value.Count == 0))
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SYSTEM_SKIP);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- SKIPPED. Nothing to configure";
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+
+ // for every app to be run
+ foreach (KeyValuePair, List>> entry in networkAdapterPciLocationToVarious)
+ {
+ string pciLocation = entry.Key.iniValue;
+ string networkAdapterName = "";
+ string networkAdapterIp = "";
+ string networkAdapterSubnetMask = "";
+ string networkAdapterDefaultGateway = "";
+ string networkAdapterLinkSpeed = "";
+ bool enableDhcp = false;
+ List dnsServers = new List();
+
+ getNicInfo(entry.Value, ref networkAdapterName, ref networkAdapterIp,
+ ref networkAdapterSubnetMask, ref networkAdapterDefaultGateway,
+ ref networkAdapterLinkSpeed, ref enableDhcp, ref dnsServers);
+
+ ManagementObject networkAdapter = null;
+ ManagementObject networkAdapterConfiguration = null;
+
+ setupSuccessful = NetworkManagement.GetNetworkAdapterAndConfigurationBasedOnPciLocation(ref networkAdapter, ref networkAdapterConfiguration, pciLocation, ref errMsg);
+
+ if (!setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList.Add(textProp);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "- FAILED. No network card is associated with PCI Location: " + pciLocation;
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ }
+
+ if (setupSuccessful && networkAdapterLinkSpeed.Length > 0)
+ {
+ setupSuccessful = NetworkManagement.SetNetworkAdapterLinkSpeed(networkAdapter, networkAdapterConfiguration, networkAdapterLinkSpeed, ref errMsg);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting link speed to " + networkAdapterLinkSpeed + " for network adapter at PCI Location " + pciLocation;
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - FAILED. " + errMsg;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
+ }
+
+ if (setupSuccessful && networkAdapterName.Length > 0)
+ {
+ setupSuccessful = NetworkManagement.ChangeNetworkAdapterName(networkAdapter, networkAdapterConfiguration, networkAdapterName, ref errMsg);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting adapter name to " + networkAdapterName + " for network adapter at PCI Location " + pciLocation;
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - FAILED. " + errMsg;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
+ }
+
+ if (setupSuccessful)
+ {
+ if (enableDhcp)
+ {
+ setupSuccessful = NetworkManagement.SetNetworkAdapterForDhcp(networkAdapter, networkAdapterConfiguration, ref errMsg);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Enabling DHCP for network adapter at PCI Location " + pciLocation;
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - FAILED. " + errMsg;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
+ }
+ else
+ {
+ if (setupSuccessful && networkAdapterIp.Length > 0 && networkAdapterSubnetMask.Length > 0)
+ {
+ setupSuccessful = NetworkManagement.SetNetworkAdapterIpAddress(networkAdapterConfiguration, networkAdapterIp, networkAdapterSubnetMask, ref errMsg);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting IP=" + networkAdapterIp + " and subnet=" + networkAdapterSubnetMask + " for network adapter at PCI Location " + pciLocation;
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - FAILED. " + errMsg;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
+ }
+
+ if (setupSuccessful && networkAdapterDefaultGateway.Length > 0 )
+ {
+ setupSuccessful = NetworkManagement.SetNetworkAdapterDefaultGateway(networkAdapterConfiguration, networkAdapterDefaultGateway, ref errMsg);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting default gateway=" + networkAdapterDefaultGateway + " for network adapter at PCI Location " + pciLocation;
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - FAILED. " + errMsg;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
+ }
+
+ if (setupSuccessful && dnsServers.Count > 0)
+ {
+ setupSuccessful = NetworkManagement.SetNetworkAdapterDnsServers(networkAdapter, networkAdapterConfiguration, dnsServers, ref errMsg);
+
+ indentation = Common.getIndentation(1);
+ msg = "\n" + indentation + "Setting DNS Server1=" + dnsServers[0];
+
+ if (dnsServers.Count > 1)
+ msg += " and Server2=" + dnsServers[1];
+
+ msg += " for network adapter at PCI Location " + pciLocation;
+
+ if (setupSuccessful)
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.SUCCESS);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - SUCCESS";
+ }
+ else
+ {
+ // set font to default text and color
+ textProp.textFont = defaultTextProp.textFont;
+ textProp.textColor = Common.getSetupStatusColor(Common.EXECUTION_STATUS.FAILURE);
+ textProp.wordIndex = 0;
+ textProp.wordCount = 2;
+ // set font style
+ textProp.textFont = new Font(textProp.textFont, FontStyle.Bold);
+ textPropList2.Add(textProp);
+
+ msg2 = " - FAILED. " + errMsg;
+ }
+
+ UpdateStatusDisplayAndLogEvent(msg, msg, textPropList);
+ UpdateStatusDisplayAndLogEvent(msg2, msg2, textPropList2);
+ }
+ }
+ }
+
+ if (!setupSuccessful)
+ break;
+ }
+ }
+
+ return setupSuccessful;
+ }
+
+ // get all the necessary info if user choose to verify software by looking at the registry
+ public void getNicInfo(List> iniKeys,
+ ref string networkAdapterName,
+ ref string networkAdapterIp, ref string networkAdapterSubnetMask,
+ ref string networkAdapterDefaultGateway, ref string networkAdapterLinkSpeed,
+ ref bool enableDhcp, ref List dnsServers)
+ {
+ // for every key specified for the app to be installed/checked
+ foreach (ConfigFileManager.Ini_KeyValue iniKey in iniKeys)
+ {
+ if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_adapter_name$", RegexOptions.IgnoreCase))
+ {
+ networkAdapterName = iniKey.iniValue;
+ }
+ else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_ip_and_subnet$", RegexOptions.IgnoreCase))
+ {
+ string[] ips = iniKey.iniValue.Split(',');
+ networkAdapterIp = ips[0].Trim();
+ networkAdapterSubnetMask = ips[1].Trim();
+ }
+ else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_default_gateway$", RegexOptions.IgnoreCase))
+ {
+ networkAdapterDefaultGateway = iniKey.iniValue;
+ }
+ else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_link_speed$", RegexOptions.IgnoreCase))
+ {
+ networkAdapterLinkSpeed = iniKey.iniValue;
+ }
+ else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_enable_dhcp$", RegexOptions.IgnoreCase))
+ {
+ if (String.Equals(iniKey.iniValue, "true", StringComparison.OrdinalIgnoreCase))
+ enableDhcp = true;
+ else
+ enableDhcp = false;
+ }
+ else if (Regex.IsMatch(iniKey.iniKeyName, @"nic\d+_dns_servers$", RegexOptions.IgnoreCase))
+ {
+ string[] ips = iniKey.iniValue.Split(',');
+ ips[0] = ips[0].Trim();
+
+ if (ips.Length > 1)
+ ips[1] = ips[1].Trim();
+
+ dnsServers = new List(ips);
+ }
+ }
+ }
+
+ bool verifyConfigInfo()
+ {
+ bool setupSuccessful = true;
+ ConfigFileManager.Ini_KeyValue iniVal = new ConfigFileManager.Ini_KeyValue