From 50b6fc9b6b3497f201ec48b0121e07ddd2a879ee Mon Sep 17 00:00:00 2001 From: David Poindexter Date: Sun, 22 Nov 2020 18:08:48 -0500 Subject: [PATCH] 2.0.0 Release (#296) * Refactor Project (#259) * Refactor phase one * Refactor phase two * Refactor phase three * Resolve issue deleting special files and folders, like .git (#261) * Add check for online connectivity and logic based on that check (#262) * Adds stylecop and fxcop to the project (#263) * - Implemented fxcop - Implemented stylecop - Refactored DatabaseController - Did some automated fixed on whole project * Implemented the rest of the stylecop/fxcop warning * Add SQL Server Authentication User Name to user settings for rememberance (#264) * Standardize all dialogs (#265) * Add custom YesNo message box and replace all default YesNo MessageBox implementations * Add custom OK message box and refactor * Move custom message box controls to new namespace * Add folders for Exceptions classes (#267) * Adds option to delete existing sites (#268) Allows deleting sites create by nvQuickSite togehter with the database and files and hosts file entry, etc. * Resolves cursor appearance issue for the View Existing Sites button (#270) * Updated ViewExistingSites to refine the design (#272) * Add setting for enabling the ability to install local packages (#273) * Implemented logging in application (#274) * Implemented logging in application - Adds basic logging in most crytical code paths - Adds ability to change logging level at runtime without restarting the app - Does not remember the log level currently between runs, this is easy to change, I was debating either to implement this or not. - Set to log Information level so logs informational things as well as errors by default. - Raising the level to Debug or more will log more granular information * Fixed an issue that prevented setting log levels * Update nvQuickSite/Controllers/DatabaseController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/DatabaseController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/FileSystemController.cs Co-authored-by: David Poindexter * Update nvQuickSite/UserSettings.cs Co-authored-by: David Poindexter * Update nvQuickSite/UserSettings.cs Co-authored-by: David Poindexter * Update nvQuickSite/UserSettings.cs Co-authored-by: David Poindexter * Update nvQuickSite/UserSettings.cs Co-authored-by: David Poindexter * Update nvQuickSite/UserSettings.cs Co-authored-by: David Poindexter * Update nvQuickSite/Program.cs Co-authored-by: David Poindexter * Update nvQuickSite/Main.cs Co-authored-by: David Poindexter * Update nvQuickSite/Main.cs Co-authored-by: David Poindexter * Update nvQuickSite/Main.cs Co-authored-by: David Poindexter * Update nvQuickSite/Main.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/VersionController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/PackageController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/IISController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/IISController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/IISController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Controllers/IISController.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter * Update nvQuickSite/Start.cs Co-authored-by: David Poindexter Co-authored-by: David Poindexter * Refine User Settings UI and fix casing for Logs folder (#277) * Disable min, max, resize for dialogs and move User Settings, View Existing Sites, Delete Sites to Controls namespace (#281) * Allows deleting a site that is not started (#286) Closes #282 - Refactored some methods to not mix reusable logic with the UI focused classes. - Added more logging in the sites deletion code paths. - Reworked site and appPool stopping logic to avoid throwing exceptions on states that don't prevent the site deletion. * Move logging of user settings values to DBG instead of INF (#287) * Adds a link to the logs folder in the settings (#289) * Adds a link to the logs folder in the settings This allows users easy access to the logs * Renamed link for clarity * Fixes Typo and adjust logging (#290) - Fixes a typo in last step - Removes unused usings - Adjusts file deletion logging to not log too much in default level (get's called recursifvelly) * Add winget manifest for 1.4.2 (#291) * Improve visual and placement of View Logs feature and utilize Hand cursor where appropriate (#294) * Update version number to 2.0.0 (#295) Co-authored-by: Daniel Valadas --- nvQuickSite/.editorconfig | 593 ++++++++ nvQuickSite/CodePlexRSS.cs | 175 --- nvQuickSite/ComboItem.cs | 62 +- nvQuickSite/Controllers/DatabaseController.cs | 268 ++++ nvQuickSite/Controllers/DialogController.cs | 107 ++ .../Exceptions/DatabaseControllerException.cs | 65 + .../FileSystemControllerException.cs | 65 + .../Exceptions/IISControllerException.cs | 65 + .../Exceptions/SiteExistsException.cs | 65 + .../Exceptions/VersionControllerException.cs | 65 + .../Controllers/FileSystemController.cs | 428 ++++++ nvQuickSite/Controllers/IISController.cs | 331 +++++ nvQuickSite/Controllers/PackageController.cs | 203 ++- nvQuickSite/Controllers/VersionController.cs | 82 +- .../Controls/Dialogs/MsgBoxOk.Designer.cs | 107 ++ nvQuickSite/Controls/Dialogs/MsgBoxOk.cs | 43 + .../Dialogs/MsgBoxOk.resx} | 0 .../Controls/Dialogs/MsgBoxYesNo.Designer.cs | 120 ++ nvQuickSite/Controls/Dialogs/MsgBoxYesNo.cs | 43 + .../Dialogs/MsgBoxYesNo.resx} | 0 .../Dialogs}/MsgBoxYesNoIgnore.Designer.cs | 54 +- .../Controls/Dialogs/MsgBoxYesNoIgnore.cs | 50 + .../Controls/Dialogs/MsgBoxYesNoIgnore.resx | 120 ++ .../Settings}/UserSettings.Designer.cs | 83 +- nvQuickSite/Controls/Settings/UserSettings.cs | 107 ++ .../Controls/Settings/UserSettings.resx | 120 ++ .../Sites/DeleteSiteProgress.Designer.cs | 291 ++++ .../Controls/Sites/DeleteSiteProgress.cs | 242 +++ .../Controls/Sites/DeleteSiteProgress.resx | 120 ++ .../Sites/ViewExistingSites.Designer.cs | 175 +++ .../Controls/Sites/ViewExistingSites.cs | 125 ++ .../Controls/Sites/ViewExistingSites.resx | 120 ++ .../Exceptions/ReadAndExtractException.cs | 65 + nvQuickSite/Main.Designer.cs | 30 +- nvQuickSite/Main.cs | 118 +- nvQuickSite/Main.resx | 2 +- nvQuickSite/Models/Package.cs | 70 +- nvQuickSite/Models/Version.cs | 40 +- nvQuickSite/MsgBoxYesNoIgnore.cs | 42 - nvQuickSite/Program.cs | 75 +- nvQuickSite/Properties/AssemblyInfo.cs | 38 +- nvQuickSite/Properties/Resources.Designer.cs | 12 +- nvQuickSite/Properties/Resources.resx | 7 +- nvQuickSite/Properties/Settings.Designer.cs | 26 +- nvQuickSite/Properties/Settings.settings | 6 + nvQuickSite/Resources/._logs-icon.png | Bin 0 -> 4096 bytes nvQuickSite/Resources/logs-icon.png | Bin 0 -> 1134 bytes nvQuickSite/Settings.cs | 71 +- nvQuickSite/Start.Designer.cs | 293 ++-- nvQuickSite/Start.cs | 1309 ++++++----------- nvQuickSite/UserSettings.cs | 46 - nvQuickSite/app.config | 6 + nvQuickSite/data/latestVersion.json | 2 +- ....GeneratedMSBuildEditorConfig.editorconfig | 36 + nvQuickSite/nvQuickSite.csproj | 92 +- nvQuickSite/stylecop.json | 48 + .../nvQuickSiteInstaller.vdproj | 196 ++- winget/manifests/1.4.2.yaml | 15 + 58 files changed, 5529 insertions(+), 1610 deletions(-) create mode 100644 nvQuickSite/.editorconfig delete mode 100644 nvQuickSite/CodePlexRSS.cs create mode 100644 nvQuickSite/Controllers/DatabaseController.cs create mode 100644 nvQuickSite/Controllers/DialogController.cs create mode 100644 nvQuickSite/Controllers/Exceptions/DatabaseControllerException.cs create mode 100644 nvQuickSite/Controllers/Exceptions/FileSystemControllerException.cs create mode 100644 nvQuickSite/Controllers/Exceptions/IISControllerException.cs create mode 100644 nvQuickSite/Controllers/Exceptions/SiteExistsException.cs create mode 100644 nvQuickSite/Controllers/Exceptions/VersionControllerException.cs create mode 100644 nvQuickSite/Controllers/FileSystemController.cs create mode 100644 nvQuickSite/Controllers/IISController.cs create mode 100644 nvQuickSite/Controls/Dialogs/MsgBoxOk.Designer.cs create mode 100644 nvQuickSite/Controls/Dialogs/MsgBoxOk.cs rename nvQuickSite/{MsgBoxYesNoIgnore.resx => Controls/Dialogs/MsgBoxOk.resx} (100%) create mode 100644 nvQuickSite/Controls/Dialogs/MsgBoxYesNo.Designer.cs create mode 100644 nvQuickSite/Controls/Dialogs/MsgBoxYesNo.cs rename nvQuickSite/{UserSettings.resx => Controls/Dialogs/MsgBoxYesNo.resx} (100%) rename nvQuickSite/{ => Controls/Dialogs}/MsgBoxYesNoIgnore.Designer.cs (65%) create mode 100644 nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.cs create mode 100644 nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.resx rename nvQuickSite/{ => Controls/Settings}/UserSettings.Designer.cs (57%) create mode 100644 nvQuickSite/Controls/Settings/UserSettings.cs create mode 100644 nvQuickSite/Controls/Settings/UserSettings.resx create mode 100644 nvQuickSite/Controls/Sites/DeleteSiteProgress.Designer.cs create mode 100644 nvQuickSite/Controls/Sites/DeleteSiteProgress.cs create mode 100644 nvQuickSite/Controls/Sites/DeleteSiteProgress.resx create mode 100644 nvQuickSite/Controls/Sites/ViewExistingSites.Designer.cs create mode 100644 nvQuickSite/Controls/Sites/ViewExistingSites.cs create mode 100644 nvQuickSite/Controls/Sites/ViewExistingSites.resx create mode 100644 nvQuickSite/Exceptions/ReadAndExtractException.cs delete mode 100644 nvQuickSite/MsgBoxYesNoIgnore.cs create mode 100644 nvQuickSite/Resources/._logs-icon.png create mode 100644 nvQuickSite/Resources/logs-icon.png delete mode 100644 nvQuickSite/UserSettings.cs create mode 100644 nvQuickSite/nvQuickSite.GeneratedMSBuildEditorConfig.editorconfig create mode 100644 nvQuickSite/stylecop.json create mode 100644 winget/manifests/1.4.2.yaml diff --git a/nvQuickSite/.editorconfig b/nvQuickSite/.editorconfig new file mode 100644 index 00000000..9004690b --- /dev/null +++ b/nvQuickSite/.editorconfig @@ -0,0 +1,593 @@ +# NOTE: Requires **VS2019 16.3** or later + +# StyleCop.Analyzers rules with default action +# Description: StyleCop.Analyzers with default action. Rules with IsEnabledByDefault = false are disabled. + +# Code files +[*.{cs,vb}] + + +# XML comment analysis disabled +dotnet_diagnostic.SA0001.severity = warning + +# Invalid settings file +dotnet_diagnostic.SA0002.severity = warning + +# Keywords should be spaced correctly +dotnet_diagnostic.SA1000.severity = warning + +# Commas should be spaced correctly +dotnet_diagnostic.SA1001.severity = warning + +# Semicolons should be spaced correctly +dotnet_diagnostic.SA1002.severity = warning + +# Symbols should be spaced correctly +dotnet_diagnostic.SA1003.severity = warning + +# Documentation lines should begin with single space +dotnet_diagnostic.SA1004.severity = warning + +# Single line comments should begin with single space +dotnet_diagnostic.SA1005.severity = warning + +# Preprocessor keywords should not be preceded by space +dotnet_diagnostic.SA1006.severity = warning + +# Operator keyword should be followed by space +dotnet_diagnostic.SA1007.severity = warning + +# Opening parenthesis should be spaced correctly +dotnet_diagnostic.SA1008.severity = warning + +# Closing parenthesis should be spaced correctly +dotnet_diagnostic.SA1009.severity = warning + +# Opening square brackets should be spaced correctly +dotnet_diagnostic.SA1010.severity = warning + +# Closing square brackets should be spaced correctly +dotnet_diagnostic.SA1011.severity = warning + +# Opening braces should be spaced correctly +dotnet_diagnostic.SA1012.severity = warning + +# Closing braces should be spaced correctly +dotnet_diagnostic.SA1013.severity = warning + +# Opening generic brackets should be spaced correctly +dotnet_diagnostic.SA1014.severity = warning + +# Closing generic brackets should be spaced correctly +dotnet_diagnostic.SA1015.severity = warning + +# Opening attribute brackets should be spaced correctly +dotnet_diagnostic.SA1016.severity = warning + +# Closing attribute brackets should be spaced correctly +dotnet_diagnostic.SA1017.severity = warning + +# Nullable type symbols should be spaced correctly +dotnet_diagnostic.SA1018.severity = warning + +# Member access symbols should be spaced correctly +dotnet_diagnostic.SA1019.severity = warning + +# Increment decrement symbols should be spaced correctly +dotnet_diagnostic.SA1020.severity = warning + +# Negative signs should be spaced correctly +dotnet_diagnostic.SA1021.severity = warning + +# Positive signs should be spaced correctly +dotnet_diagnostic.SA1022.severity = warning + +# Dereference and access of symbols should be spaced correctly +dotnet_diagnostic.SA1023.severity = warning + +# Colons should be spaced correctly +dotnet_diagnostic.SA1024.severity = warning + +# Code should not contain multiple whitespace in a row +dotnet_diagnostic.SA1025.severity = warning + +# Code should not contain space after new or stackalloc keyword in implicitly typed array allocation +dotnet_diagnostic.SA1026.severity = warning + +# Use tabs correctly +dotnet_diagnostic.SA1027.severity = warning + +# Code should not contain trailing whitespace +dotnet_diagnostic.SA1028.severity = warning + +# Do not prefix calls with base unless local implementation exists +dotnet_diagnostic.SA1100.severity = warning + +# Prefix local calls with this +dotnet_diagnostic.SA1101.severity = warning + +# Query clause should follow previous clause +dotnet_diagnostic.SA1102.severity = warning + +# Query clauses should be on separate lines or all on one line +dotnet_diagnostic.SA1103.severity = warning + +# Query clause should begin on new line when previous clause spans multiple lines +dotnet_diagnostic.SA1104.severity = warning + +# Query clauses spanning multiple lines should begin on own line +dotnet_diagnostic.SA1105.severity = warning + +# Code should not contain empty statements +dotnet_diagnostic.SA1106.severity = warning + +# Code should not contain multiple statements on one line +dotnet_diagnostic.SA1107.severity = warning + +# Block statements should not contain embedded comments +dotnet_diagnostic.SA1108.severity = warning + +# Block statements should not contain embedded regions +dotnet_diagnostic.SA1109.severity = none + +# Opening parenthesis or bracket should be on declaration line +dotnet_diagnostic.SA1110.severity = warning + +# Closing parenthesis should be on line of last parameter +dotnet_diagnostic.SA1111.severity = warning + +# Closing parenthesis should be on line of opening parenthesis +dotnet_diagnostic.SA1112.severity = warning + +# Comma should be on the same line as previous parameter +dotnet_diagnostic.SA1113.severity = warning + +# Parameter list should follow declaration +dotnet_diagnostic.SA1114.severity = warning + +# Parameter should follow comma +dotnet_diagnostic.SA1115.severity = warning + +# Split parameters should start on line after declaration +dotnet_diagnostic.SA1116.severity = warning + +# Parameters should be on same line or separate lines +dotnet_diagnostic.SA1117.severity = warning + +# Parameter should not span multiple lines +dotnet_diagnostic.SA1118.severity = warning + +# Statement should not use unnecessary parenthesis +dotnet_diagnostic.SA1119.severity = warning + +# Comments should contain text +dotnet_diagnostic.SA1120.severity = warning + +# Use built-in type alias +dotnet_diagnostic.SA1121.severity = warning + +# Use string.Empty for empty strings +dotnet_diagnostic.SA1122.severity = warning + +# Do not place regions within elements +dotnet_diagnostic.SA1123.severity = warning + +# Do not use regions +dotnet_diagnostic.SA1124.severity = warning + +# Use shorthand for nullable types +dotnet_diagnostic.SA1125.severity = warning + +# Prefix calls correctly +dotnet_diagnostic.SA1126.severity = none + +# Generic type constraints should be on their own line +dotnet_diagnostic.SA1127.severity = warning + +# Put constructor initializers on their own line +dotnet_diagnostic.SA1128.severity = warning + +# Do not use default value type constructor +dotnet_diagnostic.SA1129.severity = warning + +# Use lambda syntax +dotnet_diagnostic.SA1130.severity = warning + +# Use readable conditions +dotnet_diagnostic.SA1131.severity = warning + +# Do not combine fields +dotnet_diagnostic.SA1132.severity = warning + +# Do not combine attributes +dotnet_diagnostic.SA1133.severity = warning + +# Attributes should not share line +dotnet_diagnostic.SA1134.severity = warning + +# Using directives should be qualified +dotnet_diagnostic.SA1135.severity = warning + +# Enum values should be on separate lines +dotnet_diagnostic.SA1136.severity = warning + +# Elements should have the same indentation +dotnet_diagnostic.SA1137.severity = warning + +# Use literal suffix notation instead of casting +dotnet_diagnostic.SA1139.severity = warning + +# Using directives should be placed correctly +dotnet_diagnostic.SA1200.severity = warning + +# Elements should appear in the correct order +dotnet_diagnostic.SA1201.severity = warning + +# Elements should be ordered by access +dotnet_diagnostic.SA1202.severity = warning + +# Constants should appear before fields +dotnet_diagnostic.SA1203.severity = warning + +# Static elements should appear before instance elements +dotnet_diagnostic.SA1204.severity = warning + +# Partial elements should declare access +dotnet_diagnostic.SA1205.severity = warning + +# Declaration keywords should follow order +dotnet_diagnostic.SA1206.severity = warning + +# Protected should come before internal +dotnet_diagnostic.SA1207.severity = warning + +# System using directives should be placed before other using directives +dotnet_diagnostic.SA1208.severity = warning + +# Using alias directives should be placed after other using directives +dotnet_diagnostic.SA1209.severity = warning + +# Using directives should be ordered alphabetically by namespace +dotnet_diagnostic.SA1210.severity = warning + +# Using alias directives should be ordered alphabetically by alias name +dotnet_diagnostic.SA1211.severity = warning + +# Property accessors should follow order +dotnet_diagnostic.SA1212.severity = warning + +# Event accessors should follow order +dotnet_diagnostic.SA1213.severity = warning + +# Readonly fields should appear before non-readonly fields +dotnet_diagnostic.SA1214.severity = warning + +# Using static directives should be placed at the correct location +dotnet_diagnostic.SA1216.severity = warning + +# Using static directives should be ordered alphabetically +dotnet_diagnostic.SA1217.severity = warning + +# Element should begin with upper-case letter +dotnet_diagnostic.SA1300.severity = none + +# Element should begin with lower-case letter +dotnet_diagnostic.SA1301.severity = none + +# Interface names should begin with I +dotnet_diagnostic.SA1302.severity = warning + +# Const field names should begin with upper-case letter +dotnet_diagnostic.SA1303.severity = warning + +# Non-private readonly fields should begin with upper-case letter +dotnet_diagnostic.SA1304.severity = warning + +# Field names should not use Hungarian notation +dotnet_diagnostic.SA1305.severity = none + +# Field names should begin with lower-case letter +dotnet_diagnostic.SA1306.severity = warning + +# Accessible fields should begin with upper-case letter +dotnet_diagnostic.SA1307.severity = warning + +# Variable names should not be prefixed +dotnet_diagnostic.SA1308.severity = warning + +# Field names should not begin with underscore +dotnet_diagnostic.SA1309.severity = warning + +# Field names should not contain underscore +dotnet_diagnostic.SA1310.severity = warning + +# Static readonly fields should begin with upper-case letter +dotnet_diagnostic.SA1311.severity = warning + +# Variable names should begin with lower-case letter +dotnet_diagnostic.SA1312.severity = warning + +# Parameter names should begin with lower-case letter +dotnet_diagnostic.SA1313.severity = warning + +# Type parameter names should begin with T +dotnet_diagnostic.SA1314.severity = warning + +# Access modifier should be declared +dotnet_diagnostic.SA1400.severity = warning + +# Fields should be private +dotnet_diagnostic.SA1401.severity = warning + +# File may only contain a single type +dotnet_diagnostic.SA1402.severity = warning + +# File may only contain a single namespace +dotnet_diagnostic.SA1403.severity = warning + +# Code analysis suppression should have justification +dotnet_diagnostic.SA1404.severity = warning + +# Debug.Assert should provide message text +dotnet_diagnostic.SA1405.severity = warning + +# Debug.Fail should provide message text +dotnet_diagnostic.SA1406.severity = warning + +# Arithmetic expressions should declare precedence +dotnet_diagnostic.SA1407.severity = warning + +# Conditional expressions should declare precedence +dotnet_diagnostic.SA1408.severity = warning + +# Remove unnecessary code +dotnet_diagnostic.SA1409.severity = none + +# Remove delegate parenthesis when possible +dotnet_diagnostic.SA1410.severity = warning + +# Attribute constructor should not use unnecessary parenthesis +dotnet_diagnostic.SA1411.severity = warning + +# Store files as UTF-8 with byte order mark +dotnet_diagnostic.SA1412.severity = none + +# Use trailing comma in multi-line initializers +dotnet_diagnostic.SA1413.severity = warning + +# Braces for multi-line statements should not share line +dotnet_diagnostic.SA1500.severity = warning + +# Statement should not be on a single line +dotnet_diagnostic.SA1501.severity = warning + +# Element should not be on a single line +dotnet_diagnostic.SA1502.severity = warning + +# Braces should not be omitted +dotnet_diagnostic.SA1503.severity = warning + +# All accessors should be single-line or multi-line +dotnet_diagnostic.SA1504.severity = warning + +# Opening braces should not be followed by blank line +dotnet_diagnostic.SA1505.severity = warning + +# Element documentation headers should not be followed by blank line +dotnet_diagnostic.SA1506.severity = warning + +# Code should not contain multiple blank lines in a row +dotnet_diagnostic.SA1507.severity = warning + +# Closing braces should not be preceded by blank line +dotnet_diagnostic.SA1508.severity = warning + +# Opening braces should not be preceded by blank line +dotnet_diagnostic.SA1509.severity = warning + +# Chained statement blocks should not be preceded by blank line +dotnet_diagnostic.SA1510.severity = warning + +# While-do footer should not be preceded by blank line +dotnet_diagnostic.SA1511.severity = warning + +# Single-line comments should not be followed by blank line +dotnet_diagnostic.SA1512.severity = warning + +# Closing brace should be followed by blank line +dotnet_diagnostic.SA1513.severity = warning + +# Element documentation header should be preceded by blank line +dotnet_diagnostic.SA1514.severity = warning + +# Single-line comment should be preceded by blank line +dotnet_diagnostic.SA1515.severity = warning + +# Elements should be separated by blank line +dotnet_diagnostic.SA1516.severity = warning + +# Code should not contain blank lines at start of file +dotnet_diagnostic.SA1517.severity = warning + +# Use line endings correctly at end of file +dotnet_diagnostic.SA1518.severity = warning + +# Braces should not be omitted from multi-line child statement +dotnet_diagnostic.SA1519.severity = warning + +# Use braces consistently +dotnet_diagnostic.SA1520.severity = warning + +# Elements should be documented +dotnet_diagnostic.SA1600.severity = warning + +# Partial elements should be documented +dotnet_diagnostic.SA1601.severity = warning + +# Enumeration items should be documented +dotnet_diagnostic.SA1602.severity = warning + +# Documentation should contain valid XML +dotnet_diagnostic.SA1603.severity = none + +# Element documentation should have summary +dotnet_diagnostic.SA1604.severity = warning + +# Partial element documentation should have summary +dotnet_diagnostic.SA1605.severity = warning + +# Element documentation should have summary text +dotnet_diagnostic.SA1606.severity = warning + +# Partial element documentation should have summary text +dotnet_diagnostic.SA1607.severity = warning + +# Element documentation should not have default summary +dotnet_diagnostic.SA1608.severity = warning + +# Property documentation should have value +dotnet_diagnostic.SA1609.severity = none + +# Property documentation should have value text +dotnet_diagnostic.SA1610.severity = warning + +# Element parameters should be documented +dotnet_diagnostic.SA1611.severity = warning + +# Element parameter documentation should match element parameters +dotnet_diagnostic.SA1612.severity = warning + +# Element parameter documentation should declare parameter name +dotnet_diagnostic.SA1613.severity = warning + +# Element parameter documentation should have text +dotnet_diagnostic.SA1614.severity = warning + +# Element return value should be documented +dotnet_diagnostic.SA1615.severity = warning + +# Element return value documentation should have text +dotnet_diagnostic.SA1616.severity = warning + +# Void return value should not be documented +dotnet_diagnostic.SA1617.severity = warning + +# Generic type parameters should be documented +dotnet_diagnostic.SA1618.severity = warning + +# Generic type parameters should be documented partial class +dotnet_diagnostic.SA1619.severity = warning + +# Generic type parameter documentation should match type parameters +dotnet_diagnostic.SA1620.severity = warning + +# Generic type parameter documentation should declare parameter name +dotnet_diagnostic.SA1621.severity = warning + +# Generic type parameter documentation should have text +dotnet_diagnostic.SA1622.severity = warning + +# Property summary documentation should match accessors +dotnet_diagnostic.SA1623.severity = warning + +# Property summary documentation should omit accessor with restricted access +dotnet_diagnostic.SA1624.severity = warning + +# Element documentation should not be copied and pasted +dotnet_diagnostic.SA1625.severity = warning + +# Single-line comments should not use documentation style slashes +dotnet_diagnostic.SA1626.severity = warning + +# Documentation text should not be empty +dotnet_diagnostic.SA1627.severity = warning + +# Documentation text should begin with a capital letter +dotnet_diagnostic.SA1628.severity = none + +# Documentation text should end with a period +dotnet_diagnostic.SA1629.severity = warning + +# Documentation text should contain whitespace +dotnet_diagnostic.SA1630.severity = none + +# Documentation should meet character percentage +dotnet_diagnostic.SA1631.severity = none + +# Documentation text should meet minimum character length +dotnet_diagnostic.SA1632.severity = none + +# File should have header +dotnet_diagnostic.SA1633.severity = warning + +# File header should show copyright +dotnet_diagnostic.SA1634.severity = warning + +# File header should have copyright text +dotnet_diagnostic.SA1635.severity = warning + +# File header copyright text should match +dotnet_diagnostic.SA1636.severity = warning + +# File header should contain file name +dotnet_diagnostic.SA1637.severity = warning + +# File header file name documentation should match file name +dotnet_diagnostic.SA1638.severity = warning + +# File header should have summary +dotnet_diagnostic.SA1639.severity = warning + +# File header should have valid company text +dotnet_diagnostic.SA1640.severity = warning + +# File header company name text should match +dotnet_diagnostic.SA1641.severity = warning + +# Constructor summary documentation should begin with standard text +dotnet_diagnostic.SA1642.severity = warning + +# Destructor summary documentation should begin with standard text +dotnet_diagnostic.SA1643.severity = warning + +# Documentation headers should not contain blank lines +dotnet_diagnostic.SA1644.severity = none + +# Included documentation file does not exist +dotnet_diagnostic.SA1645.severity = none + +# Included documentation XPath does not exist +dotnet_diagnostic.SA1646.severity = none + +# Include node does not contain valid file and path +dotnet_diagnostic.SA1647.severity = none + +# Inheritdoc should be used with inheriting class +dotnet_diagnostic.SA1648.severity = warning + +# File name should match first type name +dotnet_diagnostic.SA1649.severity = warning + +# Element documentation should be spelled correctly +dotnet_diagnostic.SA1650.severity = none + +# Do not use placeholder elements +dotnet_diagnostic.SA1651.severity = warning + +# Do not prefix local calls with 'this.' +dotnet_diagnostic.SX1101.severity = none + +# Field names should begin with underscore +dotnet_diagnostic.SX1309.severity = none + +# Static field names should begin with underscore +dotnet_diagnostic.SX1309S.severity = none + +# CA2100: Review SQL queries for security vulnerabilities +dotnet_diagnostic.CA2100.severity = none + +# Default severity for analyzer diagnostics with category 'Globalization' +dotnet_analyzer_diagnostic.category-Globalization.severity = silent + +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = none diff --git a/nvQuickSite/CodePlexRSS.cs b/nvQuickSite/CodePlexRSS.cs deleted file mode 100644 index 77df05cb..00000000 --- a/nvQuickSite/CodePlexRSS.cs +++ /dev/null @@ -1,175 +0,0 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; - -namespace nvQuickSite -{ - /// - /// Represents a feed item. - /// - public class Item - { - public string Link { get; set; } - public string Title { get; set; } - public string Content { get; set; } - public DateTime PublishDate { get; set; } - public FeedType FeedType { get; set; } - - public Item() - { - Link = ""; - Title = ""; - Content = ""; - PublishDate = DateTime.Today; - FeedType = FeedType.Rss; - } - } - - /// - /// A simple RSS, RDF and ATOM feed parser. - /// - public class FeedParser - { - /// - /// Parses the given and returns a . - /// - /// - public IList Parse(string url, FeedType feedType) - { - switch (feedType) - { - case FeedType.Rss: - return ParseRss(url); - case FeedType.Rdf: - return ParseRdf(url); - case FeedType.Atom: - return ParseAtom(url); - default: - throw new NotSupportedException(string.Format("{0} is not supported", feedType.ToString())); - } - } - - /// - /// Parses an Atom feed and returns a . - /// - public virtual IList ParseAtom(string url) - { - try - { - XDocument doc = XDocument.Load(url); - // Feed/Entry - var entries = from item in doc.Root.Elements().Where(i => i.Name.LocalName == "entry") - select new Item - { - FeedType = FeedType.Atom, - Content = item.Elements().First(i => i.Name.LocalName == "content").Value, - Link = item.Elements().First(i => i.Name.LocalName == "link").Attribute("href").Value, - PublishDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "published").Value), - Title = item.Elements().First(i => i.Name.LocalName == "title").Value - }; - return entries.ToList(); - } - catch - { - return new List(); - } - } - - /// - /// Parses an RSS feed and returns a . - /// - public virtual IList ParseRss(string url) - { - try - { - XDocument doc = XDocument.Load(url); - // RSS/Channel/item - var entries = from item in doc.Root.Descendants().First(i => i.Name.LocalName == "channel").Elements().Where(i => i.Name.LocalName == "item") - select new Item - { - FeedType = FeedType.Rss, - Content = item.Elements().First(i => i.Name.LocalName == "description").Value, - Link = item.Elements().First(i => i.Name.LocalName == "link").Value, - PublishDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "pubDate").Value), - Title = item.Elements().First(i => i.Name.LocalName == "title").Value - }; - return entries.ToList(); - } - catch - { - return new List(); - } - } - - /// - /// Parses an RDF feed and returns a . - /// - public virtual IList ParseRdf(string url) - { - try - { - XDocument doc = XDocument.Load(url); - // is under the root - var entries = from item in doc.Root.Descendants().Where(i => i.Name.LocalName == "item") - select new Item - { - FeedType = FeedType.Rdf, - Content = item.Elements().First(i => i.Name.LocalName == "description").Value, - Link = item.Elements().First(i => i.Name.LocalName == "link").Value, - PublishDate = ParseDate(item.Elements().First(i => i.Name.LocalName == "date").Value), - Title = item.Elements().First(i => i.Name.LocalName == "title").Value - }; - return entries.ToList(); - } - catch - { - return new List(); - } - } - - private DateTime ParseDate(string date) - { - DateTime result; - if (DateTime.TryParse(date, out result)) - return result; - else - return DateTime.MinValue; - } - } - /// - /// Represents the XML format of a feed. - /// - public enum FeedType - { - /// - /// Really Simple Syndication format. - /// - Rss, - /// - /// RDF site summary format. - /// - Rdf, - /// - /// Atom Syndication format. - /// - Atom - } -} diff --git a/nvQuickSite/ComboItem.cs b/nvQuickSite/ComboItem.cs index b72f5e3b..e546766b 100644 --- a/nvQuickSite/ComboItem.cs +++ b/nvQuickSite/ComboItem.cs @@ -1,36 +1,52 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite { - class ComboItem + /// + /// Represents a combo box item. + /// + public class ComboItem { - public string Name { get; set; } - - public string Value { get; set; } - + /// + /// Initializes a new instance of the class. + /// + /// The item name. + /// The item value. public ComboItem(string name, string value) { - Name = name; Value = value; + this.Name = name; + this.Value = value; } + /// + /// Gets or sets the item name. + /// + public string Name { get; set; } + + /// + /// Gets or sets the item value. + /// + public string Value { get; set; } + + /// public override string ToString() { - return Name; + return this.Name; } } } diff --git a/nvQuickSite/Controllers/DatabaseController.cs b/nvQuickSite/Controllers/DatabaseController.cs new file mode 100644 index 00000000..128ffbb9 --- /dev/null +++ b/nvQuickSite/Controllers/DatabaseController.cs @@ -0,0 +1,268 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers +{ + using System; + using System.Data; + using System.Data.SqlClient; + + using nvQuickSite.Controllers.Exceptions; + using Serilog; + + /// + /// Controls database operations. + /// + public class DatabaseController + { + private readonly string dbName; + private readonly string dbServerName; + private readonly bool usesWindowsAuthentication; + private readonly string dbUserName; + private readonly string dbPassword; + private readonly string installFolder; + private readonly bool usesSiteSpecificAppPool; + private readonly object siteName; + + /// + /// Initializes a new instance of the class. + /// + /// The name of the database. + /// The name of the database server. + /// A value indicating whether to use windows authentication for the database. + /// The database user name, ignored if using windows authentication. + /// The database password, ignored if using widows authentication. + /// The path to the installation folder. + /// A value indicating whether the IIS site should use a dedicated App Pool. + /// The name of the website. + public DatabaseController( + string dbName, + string dbServerName, + bool usesWindowsAuthentication, + string dbUserName, + string dbPassword, + string installFolder, + bool usesSiteSpecificAppPool, + string siteName) + { + this.dbName = dbName; + this.dbServerName = dbServerName; + this.usesWindowsAuthentication = usesWindowsAuthentication; + this.dbUserName = dbUserName; + this.dbPassword = dbPassword; + this.installFolder = installFolder; + this.usesSiteSpecificAppPool = usesSiteSpecificAppPool; + this.siteName = siteName; + } + + /// + /// Drops the existing database. + /// + /// Is thrown when the database could not be dropped. + public void DropDatabase() + { + Log.Logger.Information("Dropping database {dbName}", this.dbName); + string myDBServerName = this.dbServerName; + string connectionStringAuthSection = string.Empty; + if (this.usesWindowsAuthentication) + { + connectionStringAuthSection = "Integrated Security=True;"; + } + else + { + connectionStringAuthSection = "User ID=" + this.dbUserName + ";Password=" + this.dbPassword + ";"; + } + + using (SqlConnection myConn = new SqlConnection("Server=" + myDBServerName + "; Initial Catalog=master;" + connectionStringAuthSection)) + { + string useMaster = @"USE master"; + string dropDatabase = $@"IF EXISTS(SELECT name FROM sys.databases WHERE name = '{this.dbName}') " + + $"DROP DATABASE [{this.dbName}]"; + + SqlCommand useMasterCommand = new SqlCommand(useMaster, myConn); + SqlCommand dropDatabaseCommand = new SqlCommand(dropDatabase, myConn); + + try + { + myConn.Open(); + useMasterCommand.ExecuteNonQuery(); + dropDatabaseCommand.ExecuteNonQuery(); + } + catch (Exception ex) + { + var message = $"Error attempting to drop database {this.dbName}"; + Log.Logger.Error(ex, message); + throw new DatabaseControllerException(message, ex) { Source = "Drop Database" }; + } + finally + { + useMasterCommand.Dispose(); + dropDatabaseCommand.Dispose(); + if (myConn.State == ConnectionState.Open) + { + myConn.Close(); + } + } + } + + Log.Logger.Information("Database {dbName} dropped", this.dbName); + } + + /// + /// Creates the database. + /// + public void CreateDatabase() + { + Log.Logger.Information("Creating database {dbName}", this.dbName); + string connectionStringAuthSection = string.Empty; + string connectionTimeout = "Connection Timeout=5;"; + if (this.usesWindowsAuthentication) + { + connectionStringAuthSection = "Integrated Security=True;"; + } + else + { + connectionStringAuthSection = $"User ID={this.dbUserName};Password={this.dbPassword};"; + } + + using (SqlConnection myConn = new SqlConnection($"Server={this.dbServerName}; Initial Catalog=master;{connectionStringAuthSection}{connectionTimeout}")) + { + string str = $"CREATE DATABASE [{this.dbName}] ON PRIMARY " + + $"(NAME = [{this.dbName}_Data], " + + $"FILENAME = '{this.installFolder}\\Database\\{this.dbName}_Data.mdf', " + + "SIZE = 20MB, MAXSIZE = 200MB, FILEGROWTH = 10%) " + + $"LOG ON (NAME = [{this.dbName}_Log], " + + $"FILENAME = '{this.installFolder}\\Database\\{this.dbName}_Log.ldf', " + + "SIZE = 13MB, " + + "MAXSIZE = 50MB, " + + "FILEGROWTH = 10%)"; + + SqlCommand sqlCommand = new SqlCommand(str, myConn); + try + { + myConn.Open(); + sqlCommand.ExecuteNonQuery(); + } + catch (Exception ex) + { + var message = $"Error creating database {this.dbName}"; + Log.Error(ex, message); + FileSystemController.RemoveDirectories(this.installFolder); + throw new DatabaseControllerException(message, ex) { Source = "Create Database" }; + } + finally + { + sqlCommand.Dispose(); + if (myConn.State == ConnectionState.Open) + { + myConn.Close(); + } + } + } + + Log.Information("Database {dbName} created", this.dbName); + } + + /// + /// Sets the database permissions. + /// + internal void SetDatabasePermissions() + { + Log.Logger.Information("Setting permissions on database {dbName}", this.dbName); + string connectionStringAuthSection = string.Empty; + if (this.usesWindowsAuthentication) + { + connectionStringAuthSection = "Integrated Security=True;"; + } + else + { + connectionStringAuthSection = $"User ID={this.dbUserName};Password={this.dbPassword};"; + } + + using (SqlConnection myConn = new SqlConnection($"Server={this.dbServerName}; Initial Catalog=master;{connectionStringAuthSection}")) + { + var appPoolNameFull = @"IIS APPPOOL\DefaultAppPool"; + var appPoolName = "DefaultAppPool"; + + if (this.usesSiteSpecificAppPool) + { + appPoolNameFull = $@"IIS APPPOOL\{this.siteName}_nvQuickSite"; + appPoolName = $"{this.siteName}_nvQuickSite"; + } + + SqlCommand useMaster = new SqlCommand("USE master", myConn); + SqlCommand grantLogin = new SqlCommand($"sp_grantlogin '{appPoolNameFull}'", myConn); + SqlCommand useDb = new SqlCommand($"USE [{this.dbName}]", myConn); + SqlCommand grantDbAccess = new SqlCommand($"sp_grantdbaccess '{appPoolNameFull}', '{appPoolName}'", myConn); + SqlCommand addRoleMember = new SqlCommand($"sp_addrolemember 'db_owner', '{appPoolName}'", myConn); + + try + { + myConn.Open(); + useMaster.ExecuteNonQuery(); + grantLogin.ExecuteNonQuery(); + useDb.ExecuteNonQuery(); + grantDbAccess.ExecuteNonQuery(); + addRoleMember.ExecuteNonQuery(); + } + catch (Exception ex) + { + var message = $"Error setting database permissions for database {this.dbName}"; + Log.Logger.Error(ex, message); + throw new DatabaseControllerException(message, ex) { Source = "Set Database Permissions" }; + } + finally + { + useMaster.Dispose(); + grantLogin.Dispose(); + useDb.Dispose(); + grantDbAccess.Dispose(); + addRoleMember.Dispose(); + if (myConn.State == ConnectionState.Open) + { + myConn.Close(); + } + } + } + + Log.Logger.Information("Permissions set for database {dbName}", this.dbName); + } + + /// + /// Deletes a database and optionally provides a progress report. + /// + /// An optional progress reporter. + internal void DeleteDatabase(IProgress progress) + { + Log.Information($"Deleting database {this.dbName}"); + progress?.Report(25); + try + { + progress?.Report(75); + this.DropDatabase(); + } + catch (DatabaseControllerException ex) + { + var message = $"Could not delete database {this.dbName}"; + Log.Logger.Error(message, ex); + throw new ArgumentException(message) { Source = "Delete Database Error" }; + } + + progress?.Report(100); + } + } +} diff --git a/nvQuickSite/Controllers/DialogController.cs b/nvQuickSite/Controllers/DialogController.cs new file mode 100644 index 00000000..3ebf8adf --- /dev/null +++ b/nvQuickSite/Controllers/DialogController.cs @@ -0,0 +1,107 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers +{ + using System.Drawing; + using System.Windows.Forms; + + using nvQuickSite.Controls.Dialogs; + + /// + /// Manages versions. + /// + public static class DialogController + { + /// + /// Enumeration for the type of dialog buttons for the custom message box. + /// + internal enum DialogButtons + { + /// + /// An OK button will be displayed. + /// + OK = 1, + + /// + /// A Yes and No button will be displayed. + /// + YesNo = 2, + + /// + /// A Yes and No button will be displayed, along with an Ignore checkbox. + /// + YesNoIgnore = 3, + } + + /// + /// Gets or sets a value indicating whether or not to warn again. + /// + public static bool DoNotWarnAgain { get; set; } + + /// + /// Shows a custom message box dialog. + /// + /// Title of the custom message box. + /// Message for the custom message box. + /// Icon for the bitmap image (e.g., SystemIcons.Error, SystemIcons.Warning, SystemIcons.Information). + /// Type of buttons to use for the custom message box. + /// User preference for not warning again with a dialog (i.e., no longer show the dialog). + /// DialogResult. + internal static DialogResult ShowMessage(string title, string message, Icon icon, DialogButtons dialogButtons, bool doNotWarnAgain = false) + { + var dialogTitle = title; + var dialogMessage = message; + var dialogIcon = icon.ToBitmap(); + DialogResult result; + switch (dialogButtons) + { + case DialogButtons.OK: + using (var messageBox = new MsgBoxOk(dialogTitle, dialogMessage, dialogIcon)) + { + result = messageBox.ShowDialog(); + } + + break; + case DialogButtons.YesNo: + using (var messageBox = new MsgBoxYesNo(dialogTitle, dialogMessage, dialogIcon)) + { + result = messageBox.ShowDialog(); + } + + break; + case DialogButtons.YesNoIgnore: + using (var messageBox = new MsgBoxYesNoIgnore(doNotWarnAgain, dialogTitle, dialogMessage, dialogIcon)) + { + result = messageBox.ShowDialog(); + DoNotWarnAgain = messageBox.DoNotWarnAgain; + } + + break; + default: + using (var messageBox = new MsgBoxOk(dialogTitle, dialogMessage, dialogIcon)) + { + result = messageBox.ShowDialog(); + } + + break; + } + + return result; + } + } +} diff --git a/nvQuickSite/Controllers/Exceptions/DatabaseControllerException.cs b/nvQuickSite/Controllers/Exceptions/DatabaseControllerException.cs new file mode 100644 index 00000000..ce0124a8 --- /dev/null +++ b/nvQuickSite/Controllers/Exceptions/DatabaseControllerException.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers.Exceptions +{ + using System; + using System.Runtime.Serialization; + + /// + /// Thrown when a database related error occurs. + /// + [Serializable] + public class DatabaseControllerException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public DatabaseControllerException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message to display to the user. + public DatabaseControllerException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message to display to the user. + /// The details of the exception that triggered this exception. + public DatabaseControllerException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The serialization information. + /// The streaming context. + protected DatabaseControllerException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/nvQuickSite/Controllers/Exceptions/FileSystemControllerException.cs b/nvQuickSite/Controllers/Exceptions/FileSystemControllerException.cs new file mode 100644 index 00000000..916c5387 --- /dev/null +++ b/nvQuickSite/Controllers/Exceptions/FileSystemControllerException.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers.Exceptions +{ + using System; + using System.Runtime.Serialization; + + /// + /// Thrown when an error occurs in the . + /// + [Serializable] + public class FileSystemControllerException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public FileSystemControllerException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message. + public FileSystemControllerException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message. + /// A reference to the inner exception. + public FileSystemControllerException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The serialization information. + /// The streaming context. + protected FileSystemControllerException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/nvQuickSite/Controllers/Exceptions/IISControllerException.cs b/nvQuickSite/Controllers/Exceptions/IISControllerException.cs new file mode 100644 index 00000000..1bd72776 --- /dev/null +++ b/nvQuickSite/Controllers/Exceptions/IISControllerException.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers.Exceptions +{ + using System; + using System.Runtime.Serialization; + + /// + /// Thrown when an error occurs in the . + /// + [Serializable] + public class IISControllerException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public IISControllerException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message to show to the user. + public IISControllerException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message to show to the user. + /// The details of the exception that triggered this exception. + public IISControllerException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The serialization information. + /// The streaming context. + protected IISControllerException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/nvQuickSite/Controllers/Exceptions/SiteExistsException.cs b/nvQuickSite/Controllers/Exceptions/SiteExistsException.cs new file mode 100644 index 00000000..24ac06a7 --- /dev/null +++ b/nvQuickSite/Controllers/Exceptions/SiteExistsException.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers.Exceptions +{ + using System; + using System.Runtime.Serialization; + + /// + /// Thrown when a site aleady exists and the user did not allow it's deletion. + /// + [Serializable] + public class SiteExistsException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public SiteExistsException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly message to display to the user. + public SiteExistsException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly message to display to the user. + /// The details of the exception that triggered this exception. + public SiteExistsException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The serialization information. + /// The streaming context. + protected SiteExistsException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/nvQuickSite/Controllers/Exceptions/VersionControllerException.cs b/nvQuickSite/Controllers/Exceptions/VersionControllerException.cs new file mode 100644 index 00000000..259d1a48 --- /dev/null +++ b/nvQuickSite/Controllers/Exceptions/VersionControllerException.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers.Exceptions +{ + using System; + using System.Runtime.Serialization; + + /// + /// Thrown when an error occurs in the . + /// + [Serializable] + public class VersionControllerException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public VersionControllerException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message to display to the user. + public VersionControllerException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly error message to display to the user. + /// The details of the exception that triggered this exception. + public VersionControllerException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The serialization information. + /// The streaming context. + protected VersionControllerException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/nvQuickSite/Controllers/FileSystemController.cs b/nvQuickSite/Controllers/FileSystemController.cs new file mode 100644 index 00000000..7bf91d01 --- /dev/null +++ b/nvQuickSite/Controllers/FileSystemController.cs @@ -0,0 +1,428 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers +{ + using System; + using System.IO; + using System.Linq; + using System.Security.AccessControl; + using System.Xml.Linq; + + using nvQuickSite.Controllers.Exceptions; + using Serilog; + + /// + /// Controls file system operations. + /// + public static class FileSystemController + { + private static string hostsFile => Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\drivers\etc\hosts"; + + /// + /// Checks if a directory is empty. + /// + /// The path to the directory to check. + /// A value indicating whether the directory is empty. + internal static bool DirectoryEmpty(string path) + { + return !Directory.EnumerateFileSystemEntries(path).Any(); + } + + /// + /// Removes an existing host entry. + /// + /// The site alias to remove. + /// A progress reported (optional). + internal static void RemoveHostEntry(string siteName, IProgress progress = null) + { + Log.Logger.Information("Removing host file entry for {siteName}", siteName); + string tempFile = hostsFile + ".new"; + var lineCount = File.ReadAllLines(hostsFile).Length; + int currentLine = 0; + + using (var sr = new StreamReader(hostsFile)) + using (var sw = new StreamWriter(tempFile)) + { + string line; + + while ((line = sr.ReadLine()) != null) + { + currentLine++; + int percent = currentLine / lineCount; + if (percent < 100) + { + progress?.Report(percent); + } + + if (!line.Contains(siteName)) + { + sw.WriteLine(line); + } + } + } + + File.Delete(hostsFile); + File.Move(tempFile, hostsFile); + Log.Logger.Debug("{hostsfile} replaced", hostsFile); + + progress?.Report(100); + } + + /// + /// Adds the site alias to the operating system hosts file. + /// + /// The alias of the site. + internal static void UpdateHostsFile(string siteName) + { + try + { + var newEntry = "\t127.0.0.1 \t" + siteName; + if (!File.ReadAllLines(hostsFile).Contains(newEntry)) + { + if (File.ReadAllText(hostsFile).EndsWith(Environment.NewLine, StringComparison.OrdinalIgnoreCase)) + { + using (StreamWriter w = File.AppendText(hostsFile)) + { + w.WriteLine(newEntry); + } + } + else + { + using (StreamWriter w = File.AppendText(hostsFile)) + { + w.WriteLine(Environment.NewLine + newEntry); + } + } + + Log.Logger.Information("{siteName} added to {hostsFile}", siteName, hostsFile); + return; + } + + Log.Logger.Information("{siteName} already in {hostsFile}", siteName, hostsFile); + } + catch (Exception ex) + { + string errorMessage = ex.Message; + if (errorMessage.IndexOf("is denied", StringComparison.OrdinalIgnoreCase) > 0) + { + errorMessage += + "\r\r\nnvQuickSite is unable to add a new host entry to the above file. Please make sure the file is not read only. If it's not, make sure your antivirus software is not blocking changes made to the file. You can pause your antivirus software until nvQuickSite has completed its work, or add an exception for nvQuickSite in the antivirus software."; + } + + Log.Logger.Error(ex, "Failed to edit {hostsFile}", hostsFile); + throw new FileSystemControllerException(errorMessage, ex) { Source = "Update Hosts File" }; + } + } + + /// + /// Creates the directories needed to host the site. + /// + /// The path to the installation folder. + /// The name of the website. + /// A value indicating whether to use a site specific App Pool. + /// The name of the database instance. + /// The name of the database server. + /// A value indicating whether to use windows authentication for the databas access. + /// The database username. + /// The database password. + internal static void CreateDirectories(string installFolder, string siteName, bool useSiteSpecificAppPool, string dbInstanceName, string dbServerName, bool usesWindowsAuthentication, string dbUserName, string dbPassword) + { + Log.Logger.Information("Creating file system directories for {siteName}", siteName); + var websiteDir = installFolder + "\\Website"; + var logsDir = installFolder + "\\Logs"; + var databaseDir = installFolder + "\\Database"; + + var appPoolName = @"IIS APPPOOL\DefaultAppPool"; + var dbServiceAccount = GetDBServiceAccount(dbInstanceName); + var authenticatedUsers = GetAuthenticatedUsersAccount(); + + if (useSiteSpecificAppPool) + { + appPoolName = @"IIS APPPOOL\" + siteName + "_nvQuickSite"; + } + + if (!Directory.Exists(websiteDir)) + { + Directory.CreateDirectory(websiteDir); + SetFolderPermission(appPoolName, websiteDir); + SetFolderPermission(authenticatedUsers, websiteDir); + } + else + { + DeleteDirectory(websiteDir, null, true); + Directory.CreateDirectory(websiteDir); + SetFolderPermission(appPoolName, websiteDir); + SetFolderPermission(authenticatedUsers, websiteDir); + } + + if (!Directory.Exists(logsDir)) + { + Directory.CreateDirectory(logsDir); + SetFolderPermission(dbServiceAccount, logsDir); + SetFolderPermission(authenticatedUsers, logsDir); + } + else + { + DeleteDirectory(logsDir, null, true); + Directory.CreateDirectory(logsDir); + SetFolderPermission(dbServiceAccount, logsDir); + SetFolderPermission(authenticatedUsers, logsDir); + } + + if (!Directory.Exists(databaseDir)) + { + Directory.CreateDirectory(databaseDir); + SetFolderPermission(dbServiceAccount, databaseDir); + SetFolderPermission(authenticatedUsers, databaseDir); + } + else + { + if (!DirectoryEmpty(databaseDir)) + { + var myDBFile = Directory.EnumerateFiles(databaseDir, "*.mdf").First().Split('_').First().Split('\\').Last(); + DatabaseController databaseController = new DatabaseController(myDBFile, dbServerName, usesWindowsAuthentication, dbUserName, dbPassword, installFolder, useSiteSpecificAppPool, siteName); + databaseController.DropDatabase(); + } + + DeleteDirectory(databaseDir, null, true); + Directory.CreateDirectory(databaseDir); + SetFolderPermission(dbServiceAccount, databaseDir); + SetFolderPermission(authenticatedUsers, databaseDir); + } + + string[] createdFolders = { websiteDir, logsDir, databaseDir }; + Log.Logger.Information("Created folders {createdFolders}", createdFolders); + } + + /// + /// Removes hosting directories for a site. + /// + /// The path to the install folder. + internal static void RemoveDirectories(string installFolder) + { + var websiteDir = installFolder + "\\Website"; + var logsDir = installFolder + "\\Logs"; + var databaseDir = installFolder + "\\Database"; + + DeleteDirectory(websiteDir, null, true); + DeleteDirectory(logsDir, null, true); + DeleteDirectory(databaseDir, null, true); + } + + /// + /// Gets the directory used to store package downloads. + /// + /// The path to the downloads directory. + internal static string GetDownloadDirectory() + { + var downloadsDirectory = Directory.GetCurrentDirectory() + @"\Downloads\"; + Log.Logger.Debug("Downloads directory is {downloadsDirectory}", downloadsDirectory); + return downloadsDirectory; + } + + /// + /// Modifies the website web.config file as needed. + /// + /// The name of the database server. + /// A value indicating whether to use windows authentication. + /// The database username. + /// The database password. + /// The database name. + /// The path to the website hosting folder. + internal static void ModifyConfig(string dbServerName, bool usesWindowsAuthentication, string dbUserName, string dbPassword, string dbName, string installFolder) + { + try + { + Log.Logger.Information("Modifying site web.config"); + + string myDBServerName = dbServerName; + string connectionStringAuthSection = string.Empty; + if (usesWindowsAuthentication) + { + connectionStringAuthSection = "Integrated Security=True;"; + } + else + { + connectionStringAuthSection = $"User ID={dbUserName};Password={dbPassword};"; + } + + string key = "SiteSqlServer"; + string value = $"Server={dbServerName};Database={dbName};{connectionStringAuthSection}"; + + string path = Path.Combine(installFolder, "Website", "web.config"); + + var config = XDocument.Load(path); + var targetNode = config.Root.Element("connectionStrings").Element("add").Attribute("connectionString"); + targetNode.Value = value; + + var list = from appNode in config.Descendants("appSettings").Elements() + where appNode.Attribute("key").Value == key + select appNode; + + var e = list.FirstOrDefault(); + if (e != null) + { + e.Attribute("value").SetValue(value); + } + + config.Save(path); + } + catch (Exception ex) + { + const string Message = "Error attempting to modify the web.config file"; + Log.Logger.Error(ex, Message); + throw new FileSystemControllerException(Message, ex) { Source = "Modify Config" }; + } + } + + /// + /// Counts all files and directories recursively. + /// + /// The root path for which to get the count from. + /// The total number of files and directories counted recursivelly. + internal static int CountFilesAndDirectories(string targetDir) + { + try + { + var files = Directory.GetFiles(targetDir); + var directories = Directory.GetDirectories(targetDir); + + var count = files.Length; + count += directories.Length; + + foreach (var directory in directories) + { + count += CountFilesAndDirectories(directory); + } + + return count; + } + catch (DirectoryNotFoundException) + { + return 0; + } + } + + /// + /// Deletes files and directories recursivelly, optionally reporting progress. + /// + /// The target directory to delete. + /// Reports progress by firing up for each file or folder with it's name. + /// A value indicating whether to log the folder deleting informaiton. + internal static void DeleteDirectory(string targetDir, IProgress progress = null, bool log = false) + { + if (log) + { + Log.Logger.Information("Deleting directory {targetDir}", targetDir); + } + + Log.Logger.Debug("Deleting directory {targetDir}", targetDir); + + try + { + string[] files = Directory.GetFiles(targetDir); + string[] dirs = Directory.GetDirectories(targetDir); + + foreach (string file in files) + { + File.SetAttributes(file, FileAttributes.Normal); + File.Delete(file); + Log.Logger.Debug("Deleted {file}", file); + progress?.Report(file); + } + + foreach (string dir in dirs) + { + DeleteDirectory(dir, progress); + progress?.Report(dir); + } + + Directory.Delete(targetDir, false); + Log.Logger.Debug("Deleted directory {targetDir}", targetDir); + progress?.Report(targetDir); + } + catch (DirectoryNotFoundException ex) + { + Log.Logger.Error(ex, "Directory not found"); + progress?.Report(ex.Message); + } + catch (FileNotFoundException ex) + { + Log.Logger.Error(ex, "File not found"); + progress?.Report(ex.Message); + } + } + + private static string GetDBServiceAccount(string dbInstanceName) + { + string dbServiceAccount = @"NT Service\MSSQLSERVER"; + + if (dbInstanceName.IndexOf(@"\", StringComparison.OrdinalIgnoreCase) > -1) + { + dbServiceAccount = @"NT Service\MSSQL$" + dbInstanceName.Substring(dbInstanceName.LastIndexOf(@"\", StringComparison.OrdinalIgnoreCase) + 1).ToUpperInvariant(); + } + + return dbServiceAccount; + } + + private static string GetAuthenticatedUsersAccount() + { + var sid = new System.Security.Principal.SecurityIdentifier("S-1-5-11"); // Authenticated Users + var account = sid.Translate(typeof(System.Security.Principal.NTAccount)); + return account.Value; + } + + private static void SetFolderPermission(string accountName, string folderPath) + { + try + { + FileSystemRights rights; + rights = FileSystemRights.Modify; + bool modified; + + var accessRule = new FileSystemAccessRule( + accountName, + rights, + InheritanceFlags.None, + PropagationFlags.NoPropagateInherit, + AccessControlType.Allow); + + var dInfo = new DirectoryInfo(folderPath); + var dSecurity = dInfo.GetAccessControl(); + dSecurity.ModifyAccessRule(AccessControlModification.Set, accessRule, out modified); + + var accessRule2 = new FileSystemAccessRule( + accountName, + rights, + InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, + PropagationFlags.InheritOnly, + AccessControlType.Allow); + + dSecurity.ModifyAccessRule(AccessControlModification.Add, accessRule2, out modified); + + dInfo.SetAccessControl(dSecurity); + Log.Logger.Debug("Permissions for {accountName} set on folder {folderPath}", accountName, folderPath); + } + catch (Exception ex) + { + Log.Logger.Error(ex, "Error occured while attempting to set folder permissions"); + throw new FileSystemControllerException("There was a problem setting the folder permissions for folder path: " + folderPath, ex) { Source = "Set Folder Permission" }; + } + } + } +} diff --git a/nvQuickSite/Controllers/IISController.cs b/nvQuickSite/Controllers/IISController.cs new file mode 100644 index 00000000..0cf63cff --- /dev/null +++ b/nvQuickSite/Controllers/IISController.cs @@ -0,0 +1,331 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controllers +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Runtime.InteropServices; + + using Microsoft.Web.Administration; + using nvQuickSite.Controllers.Exceptions; + using Serilog; + + /// + /// Controls IIS operations. + /// + public static class IISController + { + /// + /// Creates a site in IIS. + /// + /// The name of the site. + /// The path to the hosting folder for the site. + /// A value indicating whether to use a site specific App Pool. + /// If true will delete and recreate the site. + internal static void CreateSite(string siteName, string installFolder, bool useSiteSpecificAppPool, bool deleteSiteIfExists) + { + Log.Logger.Information("Creating site {siteName} in {installFolder}", siteName, installFolder); + if (SiteExists(siteName, deleteSiteIfExists)) + { + Log.Logger.Error("Site {siteName} already exists, aborting operation", siteName); + throw new SiteExistsException("Site name (" + siteName + ") already exists.") { Source = "Create Site: Site Exists" }; + } + + try + { + var bindingInfo = "*:80:" + siteName; + + using (ServerManager iisManager = new ServerManager()) + { + Site site = iisManager.Sites.Add(siteName, "http", bindingInfo, installFolder + "\\Website"); + site.TraceFailedRequestsLogging.Enabled = true; + site.TraceFailedRequestsLogging.Directory = installFolder + "\\Logs"; + site.LogFile.Directory = installFolder + "\\Logs" + "\\W3svc" + site.Id.ToString(CultureInfo.InvariantCulture); + + if (useSiteSpecificAppPool) + { + var appPoolName = siteName + "_nvQuickSite"; + ApplicationPool newPool = iisManager.ApplicationPools.Add(appPoolName); + newPool.ManagedRuntimeVersion = "v4.0"; + site.ApplicationDefaults.ApplicationPoolName = appPoolName; + } + + iisManager.CommitChanges(); + Log.Logger.Information("Created site {siteName}", siteName); + Log.Logger.Debug("Created site {@site}", site); + } + } + catch (Exception ex) + { + var message = "Error creating site in IIS"; + Log.Logger.Error(ex, message); + throw new IISControllerException(message, ex) { Source = "Create Site" }; + } + } + + /// + /// Attempts to delete a site in IIS, optionnally reporting progress. + /// + /// The id of the site to delete. + /// The progress reporter. + /// is thrown if the site cannot be deleted. + internal static void DeleteSite(long siteId, IProgress progress = null) + { + using (var iisManager = new ServerManager()) + { + try + { + var site = iisManager.Sites.FirstOrDefault(s => s.Id == siteId); + + if (site == null) + { + Log.Logger.Error("Site with id {siteId} does not exist", siteId); + progress?.Report(100); + return; + } + + iisManager.Sites.Remove(site); + iisManager.CommitChanges(); + progress?.Report(100); + Log.Logger.Information("Site {siteName} deleted", site.Name); + } + catch (COMException ex) + { + progress?.Report(100); + var message = $"The site with id {siteId} could not be deleted"; + Log.Logger.Error(message, ex); + throw new ArgumentException(message, ex) { Source = "Site Deletion Error" }; + } + } + } + + /// + /// Attempts to delete an application pool. + /// + /// The name of the application pool. + /// The progress reporter. + /// is thrown when the application pool cannot be deleted. + internal static void DeleteAppPool(string appPoolName, IProgress progress) + { + Log.Logger.Information("Deleting application pool {appPoolName}", appPoolName); + try + { + using (var iisManager = new ServerManager()) + { + var appPool = iisManager.ApplicationPools.FirstOrDefault(a => a.Name == appPoolName); + if (appPool == null) + { + Log.Logger.Information("Application pool {appPoolName} does not exist", appPoolName); + progress?.Report(100); + return; + } + + iisManager.ApplicationPools.Remove(appPool); + iisManager.CommitChanges(); + Log.Logger.Information("Application pool {appPoolName} deleted", appPoolName); + progress?.Report(100); + } + } + catch (COMException ex) + { + progress?.Report(100); + var message = $"There was an error deleting the application pool {appPoolName}"; + Log.Logger.Error(message, ex); + throw new ArgumentException(message, ex) { Source = "Delete AppPool Error" }; + } + } + + /// + /// Gets a list of IIS sites. + /// + /// When true, will filter the results to only show sites created by this tool. + /// An enumeration of sites. + internal static IEnumerable GetSites(bool createdByThisToolOnly = false) + { + Log.Logger.Information("Getting the list of sites"); + List sites; + using (ServerManager iisManager = new ServerManager()) + { + sites = iisManager.Sites.ToList(); + Log.Logger.Debug("Found the following sites {@sites}", sites); + if (!createdByThisToolOnly) + { + return sites; + } + + sites = sites + .Where(s => + s.ApplicationDefaults.ApplicationPoolName.EndsWith( + "_nvQuickSite", + StringComparison.Ordinal)) + .ToList(); + + Log.Logger.Debug("Found the following sites created by this tool {@sites}", sites); + return sites; + } + } + + /// + /// Stops an IIS website. + /// + /// The id of the site to stop. + /// An optional progress reporter. + /// is thrown when the site cannot be stopped. + internal static void StopSite(long siteId, IProgress progress) + { + Log.Logger.Debug("Deleting site with id {siteId}", siteId); + using (var iisManager = new ServerManager()) + { + progress?.Report(25); + var site = iisManager.Sites.FirstOrDefault(s => s.Id == siteId); + if (site == null) + { + Log.Logger.Information("Site with id {siteId} does not exist", siteId); + } + + site.ServerAutoStart = false; + progress.Report(50); + if (site.State != ObjectState.Stopped) + { + try + { + var state = site.Stop(); + Log.Logger.Information("Site {siteName} is {state}", site.Name, state); + } + catch (COMException ex) + { + var message = "There was a problem stopping the site.\nAborting the site deletion."; + Log.Logger.Error(message, ex); + throw new ArgumentException(message, ex) { Source = "Stop Site Error" }; + } + } + + Log.Logger.Information("Site {siteName} was already stopped", site.Name); + progress?.Report(100); + } + } + + /// + /// Attempts to stop an application pool. + /// + /// The id of the site for which to stop the application pool. + /// An optional progress reporter. + internal static void StopAppPool(long siteId, IProgress progress) + { + progress?.Report(25); + using (var iisManager = new ServerManager()) + { + var site = iisManager.Sites.FirstOrDefault(s => s.Id == siteId); + if (site == null) + { + Log.Logger.Error("The site with id {siteId} could not be found", siteId); + throw new ArgumentException("The site could not be found, aborting.") { Source = "Site Not Found" }; + } + + var appPool = iisManager.ApplicationPools.FirstOrDefault(a => + a.Name == site.ApplicationDefaults.ApplicationPoolName); + + if (appPool == null) + { + var message = "There was a problem finding the application pool.\nAborting the site deletion."; + Log.Logger.Error(message); + throw new ArgumentException(message) { Source = "AppPool Not Found" }; + } + + var totalSitesUsingAppPool = iisManager.Sites.Count(s => s.ApplicationDefaults.ApplicationPoolName == appPool.Name); + if (totalSitesUsingAppPool > 1) + { + var message = "More than one site uses this application pool.\nAborting the site deletion."; + Log.Logger.Error(message); + throw new ArgumentException(message) { Source = "AppPool Not Specific" }; + } + + progress?.Report(50); + + try + { + appPool.AutoStart = false; + if (appPool.State != ObjectState.Stopped) + { + var state = appPool.Stop(); + Log.Logger.Information("Application Pool {appPoolName} is {state}", appPool.Name, state); + } + } + catch (COMException ex) + { + var message = "There was a problem stopping the application pool.\nAborting the site deletion."; + Log.Logger.Error(message, ex); + throw new ArgumentException(message, ex) { Source = "AppPool Error" }; + } + } + + progress?.Report(100); + } + + private static bool SiteExists(string siteName, bool deleteSiteIfExists) + { + Log.Logger.Verbose("Checking if site {siteName} exists", siteName); + bool exists = false; + using (ServerManager iisManager = new ServerManager()) + { + var sites = iisManager.Sites; + + foreach (Site site in sites) + { + if (site.Name == siteName.ToString()) + { + exists = true; + Log.Logger.Verbose("Site {siteName} exists", siteName); + if (deleteSiteIfExists) + { + Log.Logger.Verbose("The user requested for the existing site {siteName} to be deleted", siteName); + if (site.ApplicationDefaults.ApplicationPoolName == siteName + "_nvQuickSite") + { + ApplicationPoolCollection appPools = iisManager.ApplicationPools; + foreach (ApplicationPool appPool in appPools) + { + if (appPool.Name == siteName + "_nvQuickSite") + { + iisManager.ApplicationPools.Remove(appPool); + break; + } + } + } + + iisManager.Sites.Remove(site); + iisManager.CommitChanges(); + Log.Logger.Information("Site {siteName} was deleted", siteName); + exists = false; + break; + } + + break; + } + else + { + exists = false; + } + } + } + + return exists; + } + } +} diff --git a/nvQuickSite/Controllers/PackageController.cs b/nvQuickSite/Controllers/PackageController.cs index d8bb99c4..ad921879 100644 --- a/nvQuickSite/Controllers/PackageController.cs +++ b/nvQuickSite/Controllers/PackageController.cs @@ -1,71 +1,115 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using nvQuickSite.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.IO; -using System.Windows.Forms; -using Octokit; +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite.Controllers { - public class PackageController + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + + using nvQuickSite.Models; + using Octokit; + using Serilog; + + /// + /// Manages packages. + /// + public static class PackageController { + /// + /// Gets a value indicating whether the system can access the GitHub repository. + /// + internal static bool IsOnline + { + get + { + bool canRead; + try + { + using (var client = new WebClient()) + { + canRead = client.OpenRead("https://github.com/nvisionative/nvQuickSite").CanRead; + Log.Logger.Information("Internet appears to be " + (canRead ? "online" : "offline")); + return canRead; + } + } + catch (WebException ex) + { + Log.Logger.Information("Internet appears offline"); + Log.Logger.Error(ex, "Unexpected error occurred while checking internet access to GitHub repository"); + return false; + } + } + } + + /// + /// Gets the list of packages available. + /// + /// An enumeration of packages. public static IEnumerable GetPackageList() { var localPackages = GetLocalPackages(); var packages = localPackages.ToList(); - var remotePackages = GetRemotePackages(); - if (remotePackages.Count() > 0) + if (PackageController.IsOnline) { - packages = localPackages.Where(p => p.keep == true).ToList(); - foreach (var package in remotePackages) + var remotePackages = GetRemotePackages(); + if (remotePackages.Any()) { - if (packages.SingleOrDefault(p => p.did == package.did && p.version == package.version) == null) + packages = localPackages.Where(p => p.keep == true).ToList(); + foreach (var package in remotePackages) { - packages.Add(package); + if (packages.SingleOrDefault(p => p.did == package.did && p.version == package.version) == null) + { + packages.Add(package); + } } } + + var ghPackages = GetGitHubPackages(); + if (ghPackages.Any()) + { + packages = packages.Union(ghPackages).ToList(); + } } - var ghPackages = GetGitHubPackages(); - if (ghPackages.Count() > 0) - { - packages = packages.Union(ghPackages).ToList(); - } + SaveLocalPackagesFile(packages); + Log.Logger.Information("Saved local packages file"); + Log.Logger.Debug("Saved packages to local packages file: {@packages}", packages); return packages; } private static IEnumerable GetLocalPackages() { - var res = new List(); - var pfile = Directory.GetCurrentDirectory() + @"\Downloads\packages.json"; - if (File.Exists(pfile)) + var localPackages = new List(); + var packagesFile = Directory.GetCurrentDirectory() + @"\Downloads\packages.json"; + if (File.Exists(packagesFile)) { - using (var sr = new StreamReader(pfile)) + using (var sr = new StreamReader(packagesFile)) { var content = sr.ReadToEnd(); - res = Newtonsoft.Json.JsonConvert.DeserializeObject>(content); + localPackages = Newtonsoft.Json.JsonConvert.DeserializeObject>(content); } } - return res; + + Log.Logger.Information("Loaded local packages"); + Log.Logger.Debug("Loaded local packages: {@localPackages}", localPackages); + return localPackages; } private static void SaveLocalPackagesFile(IEnumerable packages) @@ -85,18 +129,23 @@ private static void SaveLocalPackagesFile(IEnumerable packages) private static IEnumerable GetRemotePackages() { - WebClient client = new WebClient(); - try - { - var url = "https://github.com/nvisionative/nvQuickSite/raw/master/nvQuickSite/data/packages.json"; - string result = client.DownloadString(url); - var res = Newtonsoft.Json.JsonConvert.DeserializeObject>(result); - return res; - } - catch (Exception ex) + using (WebClient client = new WebClient()) { + try + { + var url = "https://github.com/nvisionative/nvQuickSite/raw/master/nvQuickSite/data/packages.json"; + string result = client.DownloadString(url); + var packages = Newtonsoft.Json.JsonConvert.DeserializeObject>(result); + Log.Logger.Information("Loaded remote packages"); + Log.Logger.Debug("Loaded remote packages: {@packages}", packages); + return packages; + } + catch (WebException ex) + { + Log.Logger.Error(ex, "Unexpected error occurred retrieving remote packages."); + return new List(); + } } - return new List(); } private static string GetDownloadDirectory() @@ -104,9 +153,13 @@ private static string GetDownloadDirectory() return Directory.GetCurrentDirectory() + @"\Downloads\"; } + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Design", + "CA1031:Do not catch general exception types", + Justification = "On purpose so any exception here does not prevent using local packages.")] private static IEnumerable GetGitHubPackages() { - var res = new List(); + var packages = new List(); try { var client = new GitHubClient(new ProductHeaderValue("nvQuickSite")); @@ -117,50 +170,68 @@ private static IEnumerable GetGitHubPackages() var index = 0; foreach (Release release in releases) { - var installPackage = release.Assets.Where(a => a.BrowserDownloadUrl.IndexOf("install", StringComparison.OrdinalIgnoreCase) > -1 && a.BrowserDownloadUrl.IndexOf("dnn_platform", StringComparison.OrdinalIgnoreCase) > -1).FirstOrDefault(); - var upgradePackage = release.Assets.Where(a => a.BrowserDownloadUrl.IndexOf("upgrade", StringComparison.OrdinalIgnoreCase) > -1 && a.BrowserDownloadUrl.IndexOf("dnn_platform", StringComparison.OrdinalIgnoreCase) > -1).FirstOrDefault(); + var installPackage = release.Assets + .Where(a => + a.BrowserDownloadUrl.IndexOf("install", StringComparison.OrdinalIgnoreCase) > -1 && + a.BrowserDownloadUrl.IndexOf("dnn_platform", StringComparison.OrdinalIgnoreCase) > -1) + .FirstOrDefault(); + + var upgradePackage = release.Assets + .Where(a => + a.BrowserDownloadUrl.IndexOf("upgrade", StringComparison.OrdinalIgnoreCase) > -1 && + a.BrowserDownloadUrl.IndexOf("dnn_platform", StringComparison.OrdinalIgnoreCase) > -1) + .FirstOrDefault(); + var ghPackage = new Package(); ghPackage.version = TrimTagName(release); - if (index == 0 && - release.Name.IndexOf("rc", StringComparison.OrdinalIgnoreCase) >= 0 && - Properties.Settings.Default.ShowReleaseCandidates && + if (index == 0 && + release.Name.IndexOf("rc", StringComparison.OrdinalIgnoreCase) >= 0 && + Properties.Settings.Default.ShowReleaseCandidates && installPackage != null) { ghPackage.did = "dnn-platform-rc"; ghPackage.name = "DNN Platform Release Candidate"; ghPackage.url = installPackage.BrowserDownloadUrl; ghPackage.upgradeurl = upgradePackage.BrowserDownloadUrl; - res.Add(ghPackage); + packages.Add(ghPackage); } - else if (!release.Name.ToLower().Contains("rc") && + else if (!release.Name.ToUpperInvariant().Contains("RC") && installPackage != null) { ghPackage.did = "dnn-platform-" + ghPackage.version.Substring(0, 1); ghPackage.name = "DNN Platform " + ghPackage.version.Substring(0, 1); ghPackage.url = installPackage.BrowserDownloadUrl; ghPackage.upgradeurl = upgradePackage.BrowserDownloadUrl; - res.Add(ghPackage); + packages.Add(ghPackage); } + index++; } } + + Log.Logger.Information("Retrieved DNN packages from GitHub"); + Log.Logger.Debug("Retrieved DNN packages from GitHub: {@packages}", packages); + return packages; } catch (Exception ex) { - MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + Log.Logger.Error(ex, "Unexpected error occurred retrieving DNN packages from GitHub"); + return packages; } - return res; } private static string TrimTagName(Release release) { if (release.TagName != null && release.TagName[0] == 'v') + { return release.TagName.Remove(0, 1); + } else + { return release.TagName; + } } - } -} \ No newline at end of file +} diff --git a/nvQuickSite/Controllers/VersionController.cs b/nvQuickSite/Controllers/VersionController.cs index eba8dc1b..880577a2 100644 --- a/nvQuickSite/Controllers/VersionController.cs +++ b/nvQuickSite/Controllers/VersionController.cs @@ -1,44 +1,60 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using System; -using System.Collections.Generic; -using System.Net; +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite.Controllers { - public class VersionController + using System.Net; + + using nvQuickSite.Controllers.Exceptions; + using Serilog; + + /// + /// Manages versions. + /// + public static class VersionController { + /// + /// Gets the latest nvQuickSite version available on Github. + /// + /// The latest version as a string. + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Security", + "CA5386:Avoid hardcoding SecurityProtocolType value", + Justification = "Workaround since Github enforces Tls12 but we don't know the user config.")] public static string GetRemoteLatestVersion() { - WebClient client = new WebClient(); - try + using (WebClient client = new WebClient()) { - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - var url = "https://raw.githubusercontent.com/nvisionative/nvQuickSite/master/nvQuickSite/data/latestVersion.json"; - string result = client.DownloadString(url); - Models.Version res = Newtonsoft.Json.JsonConvert.DeserializeObject(result); - return res.latestVersion; + try + { + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + var url = "https://raw.githubusercontent.com/nvisionative/nvQuickSite/master/nvQuickSite/data/latestVersion.json"; + string result = client.DownloadString(url); + Models.Version res = Newtonsoft.Json.JsonConvert.DeserializeObject(result); + Log.Logger.Debug("v{version} available on GitHub.", res.latestVersion); + return res.latestVersion; + } + catch (WebException ex) + { + var message = "There was an error reading the latest version of nvQuickSite. Please\ncheck your internet connection."; + Log.Logger.Error(ex, message.Replace("\n", " ")); + throw new VersionControllerException(message, ex) { Source = "Get Remote Latest Version" }; + } } - catch (Exception ex) - { - } - return ""; } - } } diff --git a/nvQuickSite/Controls/Dialogs/MsgBoxOk.Designer.cs b/nvQuickSite/Controls/Dialogs/MsgBoxOk.Designer.cs new file mode 100644 index 00000000..994fb955 --- /dev/null +++ b/nvQuickSite/Controls/Dialogs/MsgBoxOk.Designer.cs @@ -0,0 +1,107 @@ +namespace nvQuickSite.Controls.Dialogs +{ + partial class MsgBoxOk + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblTitle = new MetroFramework.Controls.MetroLabel(); + this.btnOk = new MetroFramework.Controls.MetroButton(); + this.dialogIcon = new System.Windows.Forms.PictureBox(); + this.lblMessage = new MetroFramework.Controls.MetroLabel(); + ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).BeginInit(); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.FontWeight = MetroFramework.MetroLabelWeight.Bold; + this.lblTitle.Location = new System.Drawing.Point(77, 23); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(67, 19); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "Message"; + // + // btnOk + // + this.btnOk.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnOk.DialogResult = System.Windows.Forms.DialogResult.No; + this.btnOk.Location = new System.Drawing.Point(429, 129); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size(75, 23); + this.btnOk.TabIndex = 2; + this.btnOk.Text = "OK"; + // + // dialogIcon + // + this.dialogIcon.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dialogIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.dialogIcon.Location = new System.Drawing.Point(4, 11); + this.dialogIcon.Name = "dialogIcon"; + this.dialogIcon.Size = new System.Drawing.Size(77, 77); + this.dialogIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.dialogIcon.TabIndex = 4; + this.dialogIcon.TabStop = false; + // + // lblMessage + // + this.lblMessage.AutoSize = true; + this.lblMessage.Location = new System.Drawing.Point(77, 43); + this.lblMessage.Name = "lblMessage"; + this.lblMessage.Size = new System.Drawing.Size(60, 19); + this.lblMessage.TabIndex = 5; + this.lblMessage.Text = "Message"; + // + // MsgBoxOk + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BorderStyle = MetroFramework.Drawing.MetroBorderStyle.FixedSingle; + this.ClientSize = new System.Drawing.Size(527, 170); + this.Controls.Add(this.lblTitle); + this.Controls.Add(this.lblMessage); + this.Controls.Add(this.dialogIcon); + this.Controls.Add(this.btnOk); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "MsgBoxOk"; + this.Resizable = false; + ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MetroFramework.Controls.MetroLabel lblTitle; + private MetroFramework.Controls.MetroButton btnOk; + private System.Windows.Forms.PictureBox dialogIcon; + private MetroFramework.Controls.MetroLabel lblMessage; + } +} \ No newline at end of file diff --git a/nvQuickSite/Controls/Dialogs/MsgBoxOk.cs b/nvQuickSite/Controls/Dialogs/MsgBoxOk.cs new file mode 100644 index 00000000..c8a885b2 --- /dev/null +++ b/nvQuickSite/Controls/Dialogs/MsgBoxOk.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controls.Dialogs +{ + using System.Drawing; + + using MetroFramework.Forms; + + /// + /// A custom messagebox with yes, no and ignore. + /// + public partial class MsgBoxOk : MetroForm + { + /// + /// Initializes a new instance of the class. + /// + /// The title to show in the dialog. + /// The message to show in the dialog. + /// The image to use as the dialog icon. + public MsgBoxOk(string dialogTitle, string dialogMessage, Image dialogIconImage) + { + this.InitializeComponent(); + this.lblTitle.Text = dialogTitle; + this.lblMessage.Text = dialogMessage; + this.dialogIcon.Image = dialogIconImage; + } + } +} diff --git a/nvQuickSite/MsgBoxYesNoIgnore.resx b/nvQuickSite/Controls/Dialogs/MsgBoxOk.resx similarity index 100% rename from nvQuickSite/MsgBoxYesNoIgnore.resx rename to nvQuickSite/Controls/Dialogs/MsgBoxOk.resx diff --git a/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.Designer.cs b/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.Designer.cs new file mode 100644 index 00000000..b16ef13f --- /dev/null +++ b/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.Designer.cs @@ -0,0 +1,120 @@ +namespace nvQuickSite.Controls.Dialogs +{ + partial class MsgBoxYesNo + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblTitle = new MetroFramework.Controls.MetroLabel(); + this.btnNo = new MetroFramework.Controls.MetroButton(); + this.dialogIcon = new System.Windows.Forms.PictureBox(); + this.btnYes = new MetroFramework.Controls.MetroButton(); + this.lblMessage = new MetroFramework.Controls.MetroLabel(); + ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).BeginInit(); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.FontWeight = MetroFramework.MetroLabelWeight.Bold; + this.lblTitle.Location = new System.Drawing.Point(77, 23); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(67, 19); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "Message"; + // + // btnNo + // + this.btnNo.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnNo.DialogResult = System.Windows.Forms.DialogResult.No; + this.btnNo.Location = new System.Drawing.Point(429, 129); + this.btnNo.Name = "btnNo"; + this.btnNo.Size = new System.Drawing.Size(75, 23); + this.btnNo.TabIndex = 2; + this.btnNo.Text = "No"; + // + // dialogIcon + // + this.dialogIcon.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dialogIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.dialogIcon.Location = new System.Drawing.Point(4, 11); + this.dialogIcon.Name = "dialogIcon"; + this.dialogIcon.Size = new System.Drawing.Size(77, 77); + this.dialogIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; + this.dialogIcon.TabIndex = 4; + this.dialogIcon.TabStop = false; + // + // btnYes + // + this.btnYes.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnYes.DialogResult = System.Windows.Forms.DialogResult.Yes; + this.btnYes.Location = new System.Drawing.Point(330, 129); + this.btnYes.Name = "btnYes"; + this.btnYes.Size = new System.Drawing.Size(75, 23); + this.btnYes.TabIndex = 1; + this.btnYes.Text = "Yes"; + // + // lblMessage + // + this.lblMessage.AutoSize = true; + this.lblMessage.Location = new System.Drawing.Point(77, 43); + this.lblMessage.Name = "lblMessage"; + this.lblMessage.Size = new System.Drawing.Size(60, 19); + this.lblMessage.TabIndex = 5; + this.lblMessage.Text = "Message"; + // + // MsgBoxYesNo + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BorderStyle = MetroFramework.Drawing.MetroBorderStyle.FixedSingle; + this.ClientSize = new System.Drawing.Size(527, 170); + this.Controls.Add(this.lblTitle); + this.Controls.Add(this.lblMessage); + this.Controls.Add(this.dialogIcon); + this.Controls.Add(this.btnNo); + this.Controls.Add(this.btnYes); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "MsgBoxYesNo"; + this.Resizable = false; + ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MetroFramework.Controls.MetroLabel lblTitle; + private MetroFramework.Controls.MetroButton btnNo; + private System.Windows.Forms.PictureBox dialogIcon; + private MetroFramework.Controls.MetroButton btnYes; + private MetroFramework.Controls.MetroLabel lblMessage; + } +} \ No newline at end of file diff --git a/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.cs b/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.cs new file mode 100644 index 00000000..bdb68fe3 --- /dev/null +++ b/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controls.Dialogs +{ + using System.Drawing; + + using MetroFramework.Forms; + + /// + /// A custom messagebox with yes, no and ignore. + /// + public partial class MsgBoxYesNo : MetroForm + { + /// + /// Initializes a new instance of the class. + /// + /// The title to show in the dialog. + /// The message to show in the dialog. + /// The image to use as the dialog icon. + public MsgBoxYesNo(string dialogTitle, string dialogMessage, Image dialogIconImage) + { + this.InitializeComponent(); + this.lblTitle.Text = dialogTitle; + this.lblMessage.Text = dialogMessage; + this.dialogIcon.Image = dialogIconImage; + } + } +} diff --git a/nvQuickSite/UserSettings.resx b/nvQuickSite/Controls/Dialogs/MsgBoxYesNo.resx similarity index 100% rename from nvQuickSite/UserSettings.resx rename to nvQuickSite/Controls/Dialogs/MsgBoxYesNo.resx diff --git a/nvQuickSite/MsgBoxYesNoIgnore.Designer.cs b/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.Designer.cs similarity index 65% rename from nvQuickSite/MsgBoxYesNoIgnore.Designer.cs rename to nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.Designer.cs index 538bf8e6..ea3d58a1 100644 --- a/nvQuickSite/MsgBoxYesNoIgnore.Designer.cs +++ b/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.Designer.cs @@ -1,4 +1,4 @@ -namespace nvQuickSite +namespace nvQuickSite.Controls.Dialogs { partial class MsgBoxYesNoIgnore { @@ -28,25 +28,37 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.lblTitle = new MetroFramework.Controls.MetroLabel(); this.lblMessage = new MetroFramework.Controls.MetroLabel(); this.btnYes = new MetroFramework.Controls.MetroButton(); - this.metroButton2 = new MetroFramework.Controls.MetroButton(); + this.btnNo = new MetroFramework.Controls.MetroButton(); this.chkDoNotWarnAgain = new MetroFramework.Controls.MetroCheckBox(); this.dialogIcon = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).BeginInit(); this.SuspendLayout(); // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.FontWeight = MetroFramework.MetroLabelWeight.Bold; + this.lblTitle.Location = new System.Drawing.Point(77, 23); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(67, 19); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "Message"; + // // lblMessage // this.lblMessage.AutoSize = true; - this.lblMessage.Location = new System.Drawing.Point(97, 23); + this.lblMessage.Location = new System.Drawing.Point(77, 43); this.lblMessage.Name = "lblMessage"; this.lblMessage.Size = new System.Drawing.Size(60, 19); - this.lblMessage.TabIndex = 0; + this.lblMessage.TabIndex = 5; this.lblMessage.Text = "Message"; // // btnYes // + this.btnYes.Cursor = System.Windows.Forms.Cursors.Hand; this.btnYes.DialogResult = System.Windows.Forms.DialogResult.Yes; this.btnYes.Location = new System.Drawing.Point(330, 129); this.btnYes.Name = "btnYes"; @@ -54,18 +66,20 @@ private void InitializeComponent() this.btnYes.TabIndex = 1; this.btnYes.Text = "Yes"; // - // metroButton2 + // btnNo // - this.metroButton2.DialogResult = System.Windows.Forms.DialogResult.No; - this.metroButton2.Location = new System.Drawing.Point(429, 129); - this.metroButton2.Name = "metroButton2"; - this.metroButton2.Size = new System.Drawing.Size(75, 23); - this.metroButton2.TabIndex = 2; - this.metroButton2.Text = "No"; + this.btnNo.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnNo.DialogResult = System.Windows.Forms.DialogResult.No; + this.btnNo.Location = new System.Drawing.Point(429, 129); + this.btnNo.Name = "btnNo"; + this.btnNo.Size = new System.Drawing.Size(75, 23); + this.btnNo.TabIndex = 2; + this.btnNo.Text = "No"; // // chkDoNotWarnAgain // this.chkDoNotWarnAgain.AutoSize = true; + this.chkDoNotWarnAgain.Cursor = System.Windows.Forms.Cursors.Hand; this.chkDoNotWarnAgain.Location = new System.Drawing.Point(17, 129); this.chkDoNotWarnAgain.Name = "chkDoNotWarnAgain"; this.chkDoNotWarnAgain.Size = new System.Drawing.Size(140, 15); @@ -75,9 +89,14 @@ private void InitializeComponent() // // dialogIcon // - this.dialogIcon.Location = new System.Drawing.Point(17, 35); + this.dialogIcon.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dialogIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.dialogIcon.Location = new System.Drawing.Point(4, 11); this.dialogIcon.Name = "dialogIcon"; - this.dialogIcon.Size = new System.Drawing.Size(67, 67); + this.dialogIcon.Size = new System.Drawing.Size(77, 77); + this.dialogIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; this.dialogIcon.TabIndex = 4; this.dialogIcon.TabStop = false; // @@ -87,12 +106,16 @@ private void InitializeComponent() this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BorderStyle = MetroFramework.Drawing.MetroBorderStyle.FixedSingle; this.ClientSize = new System.Drawing.Size(527, 170); + this.Controls.Add(this.lblTitle); this.Controls.Add(this.dialogIcon); this.Controls.Add(this.chkDoNotWarnAgain); - this.Controls.Add(this.metroButton2); + this.Controls.Add(this.btnNo); this.Controls.Add(this.btnYes); this.Controls.Add(this.lblMessage); + this.MaximizeBox = false; + this.MinimizeBox = false; this.Name = "MsgBoxYesNoIgnore"; + this.Resizable = false; ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -101,9 +124,10 @@ private void InitializeComponent() #endregion + private MetroFramework.Controls.MetroLabel lblTitle; private MetroFramework.Controls.MetroLabel lblMessage; private MetroFramework.Controls.MetroButton btnYes; - private MetroFramework.Controls.MetroButton metroButton2; + private MetroFramework.Controls.MetroButton btnNo; private MetroFramework.Controls.MetroCheckBox chkDoNotWarnAgain; private System.Windows.Forms.PictureBox dialogIcon; } diff --git a/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.cs b/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.cs new file mode 100644 index 00000000..5fd541d8 --- /dev/null +++ b/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controls.Dialogs +{ + using System.Drawing; + + using MetroFramework.Forms; + + /// + /// A custom messagebox with yes, no and ignore. + /// + public partial class MsgBoxYesNoIgnore : MetroForm + { + /// + /// Initializes a new instance of the class. + /// + /// A value indicating whether the Do Not Warn Again checkbox should be checked. + /// The title to show in the dialog. + /// The message to show in the dialog. + /// The image to use as the dialog icon. + public MsgBoxYesNoIgnore(bool doNotWarnAgain, string dialogTitle, string dialogMessage, Image dialogIconImage) + { + this.InitializeComponent(); + this.chkDoNotWarnAgain.Checked = doNotWarnAgain; + this.lblTitle.Text = dialogTitle; + this.lblMessage.Text = dialogMessage; + this.dialogIcon.Image = dialogIconImage; + } + + /// + /// Gets a value indicating whether to not warn again. + /// + public bool DoNotWarnAgain => this.chkDoNotWarnAgain.Checked; + } +} diff --git a/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.resx b/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/nvQuickSite/Controls/Dialogs/MsgBoxYesNoIgnore.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/nvQuickSite/UserSettings.Designer.cs b/nvQuickSite/Controls/Settings/UserSettings.Designer.cs similarity index 57% rename from nvQuickSite/UserSettings.Designer.cs rename to nvQuickSite/Controls/Settings/UserSettings.Designer.cs index 83d47326..c61dd8b8 100644 --- a/nvQuickSite/UserSettings.Designer.cs +++ b/nvQuickSite/Controls/Settings/UserSettings.Designer.cs @@ -1,4 +1,4 @@ -namespace nvQuickSite +namespace nvQuickSite.Controls.Settings { partial class UserSettings { @@ -34,7 +34,13 @@ private void InitializeComponent() this.chkShowReleaseCandidates = new MetroFramework.Controls.MetroCheckBox(); this.dialogIcon = new System.Windows.Forms.PictureBox(); this.chkShareStatistics = new MetroFramework.Controls.MetroCheckBox(); + this.chkEnableLocalPackageInstall = new MetroFramework.Controls.MetroCheckBox(); + this.cboLoggingLevel = new MetroFramework.Controls.MetroComboBox(); + this.metroLabel1 = new MetroFramework.Controls.MetroLabel(); + this.lnkViewLogs = new MetroFramework.Controls.MetroLink(); + this.logsIcon = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.logsIcon)).BeginInit(); this.SuspendLayout(); // // lblMessage @@ -52,6 +58,7 @@ private void InitializeComponent() // // btnSave // + this.btnSave.Cursor = System.Windows.Forms.Cursors.Hand; this.btnSave.DialogResult = System.Windows.Forms.DialogResult.OK; this.btnSave.Location = new System.Drawing.Point(330, 129); this.btnSave.Name = "btnSave"; @@ -61,6 +68,7 @@ private void InitializeComponent() // // metroButton2 // + this.metroButton2.Cursor = System.Windows.Forms.Cursors.Hand; this.metroButton2.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.metroButton2.Location = new System.Drawing.Point(429, 129); this.metroButton2.Name = "metroButton2"; @@ -71,6 +79,7 @@ private void InitializeComponent() // chkShowReleaseCandidates // this.chkShowReleaseCandidates.AutoSize = true; + this.chkShowReleaseCandidates.Cursor = System.Windows.Forms.Cursors.Hand; this.chkShowReleaseCandidates.Location = new System.Drawing.Point(118, 53); this.chkShowReleaseCandidates.Name = "chkShowReleaseCandidates"; this.chkShowReleaseCandidates.Size = new System.Drawing.Size(156, 15); @@ -95,6 +104,7 @@ private void InitializeComponent() this.chkShareStatistics.AutoSize = true; this.chkShareStatistics.Checked = true; this.chkShareStatistics.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkShareStatistics.Cursor = System.Windows.Forms.Cursors.Hand; this.chkShareStatistics.ForeColor = System.Drawing.SystemColors.ControlText; this.chkShareStatistics.Location = new System.Drawing.Point(118, 74); this.chkShareStatistics.Name = "chkShareStatistics"; @@ -103,20 +113,86 @@ private void InitializeComponent() this.chkShareStatistics.Text = "Share Statistics"; this.chkShareStatistics.UseVisualStyleBackColor = true; // + // chkEnableLocalPackageInstall + // + this.chkEnableLocalPackageInstall.AutoSize = true; + this.chkEnableLocalPackageInstall.Cursor = System.Windows.Forms.Cursors.Hand; + this.chkEnableLocalPackageInstall.Location = new System.Drawing.Point(118, 95); + this.chkEnableLocalPackageInstall.Name = "chkEnableLocalPackageInstall"; + this.chkEnableLocalPackageInstall.Size = new System.Drawing.Size(170, 15); + this.chkEnableLocalPackageInstall.TabIndex = 6; + this.chkEnableLocalPackageInstall.Text = "Enable Local Package Install"; + this.chkEnableLocalPackageInstall.UseVisualStyleBackColor = true; + // + // cboLoggingLevel + // + this.cboLoggingLevel.Cursor = System.Windows.Forms.Cursors.Hand; + this.cboLoggingLevel.FormattingEnabled = true; + this.cboLoggingLevel.ItemHeight = 23; + this.cboLoggingLevel.Location = new System.Drawing.Point(330, 82); + this.cboLoggingLevel.Name = "cboLoggingLevel"; + this.cboLoggingLevel.Size = new System.Drawing.Size(174, 29); + this.cboLoggingLevel.TabIndex = 7; + // + // metroLabel1 + // + this.metroLabel1.AutoSize = true; + this.metroLabel1.FontSize = MetroFramework.MetroLabelSize.Small; + this.metroLabel1.FontWeight = MetroFramework.MetroLabelWeight.Regular; + this.metroLabel1.Location = new System.Drawing.Point(330, 64); + this.metroLabel1.Name = "metroLabel1"; + this.metroLabel1.Size = new System.Drawing.Size(81, 15); + this.metroLabel1.TabIndex = 8; + this.metroLabel1.Text = "Logging Level"; + // + // lnkViewLogs + // + this.lnkViewLogs.Cursor = System.Windows.Forms.Cursors.Hand; + this.lnkViewLogs.Location = new System.Drawing.Point(420, 56); + this.lnkViewLogs.Name = "lnkViewLogs"; + this.lnkViewLogs.Size = new System.Drawing.Size(73, 23); + this.lnkViewLogs.Style = MetroFramework.MetroColorStyle.Blue; + this.lnkViewLogs.TabIndex = 9; + this.lnkViewLogs.Text = "View Logs"; + this.lnkViewLogs.TextAlign = System.Drawing.ContentAlignment.BottomRight; + this.lnkViewLogs.UseStyleColors = true; + this.lnkViewLogs.Click += new System.EventHandler(this.lnkViewLogs_Click); + // + // logsIcon + // + this.logsIcon.Cursor = System.Windows.Forms.Cursors.Hand; + this.logsIcon.Image = global::nvQuickSite.Properties.Resources.logs_icon; + this.logsIcon.Location = new System.Drawing.Point(493, 64); + this.logsIcon.Name = "logsIcon"; + this.logsIcon.Size = new System.Drawing.Size(11, 15); + this.logsIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.logsIcon.TabIndex = 10; + this.logsIcon.TabStop = false; + this.logsIcon.Click += new System.EventHandler(this.logsIcon_Click); + // // UserSettings // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BorderStyle = MetroFramework.Drawing.MetroBorderStyle.FixedSingle; this.ClientSize = new System.Drawing.Size(527, 170); + this.Controls.Add(this.logsIcon); + this.Controls.Add(this.lnkViewLogs); + this.Controls.Add(this.metroLabel1); + this.Controls.Add(this.cboLoggingLevel); + this.Controls.Add(this.chkEnableLocalPackageInstall); this.Controls.Add(this.chkShareStatistics); this.Controls.Add(this.dialogIcon); this.Controls.Add(this.chkShowReleaseCandidates); this.Controls.Add(this.metroButton2); this.Controls.Add(this.btnSave); this.Controls.Add(this.lblMessage); + this.MaximizeBox = false; + this.MinimizeBox = false; this.Name = "UserSettings"; + this.Resizable = false; ((System.ComponentModel.ISupportInitialize)(this.dialogIcon)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.logsIcon)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -130,5 +206,10 @@ private void InitializeComponent() private MetroFramework.Controls.MetroCheckBox chkShowReleaseCandidates; private System.Windows.Forms.PictureBox dialogIcon; private MetroFramework.Controls.MetroCheckBox chkShareStatistics; + private MetroFramework.Controls.MetroCheckBox chkEnableLocalPackageInstall; + private MetroFramework.Controls.MetroComboBox cboLoggingLevel; + private MetroFramework.Controls.MetroLabel metroLabel1; + private MetroFramework.Controls.MetroLink lnkViewLogs; + private System.Windows.Forms.PictureBox logsIcon; } } \ No newline at end of file diff --git a/nvQuickSite/Controls/Settings/UserSettings.cs b/nvQuickSite/Controls/Settings/UserSettings.cs new file mode 100644 index 00000000..4142b1f4 --- /dev/null +++ b/nvQuickSite/Controls/Settings/UserSettings.cs @@ -0,0 +1,107 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controls.Settings +{ + using System; + using System.Diagnostics; + using System.IO; + using System.Linq; + + using MetroFramework.Controls; + using MetroFramework.Forms; + using Serilog; + using Serilog.Core; + using Serilog.Events; + + /// + /// Implementes the user specific settings form. + /// + public partial class UserSettings : MetroForm + { + private readonly LoggingLevelSwitch loggingLevelSwitch; + + /// + /// Initializes a new instance of the class. + /// + /// An object used to change logging level at runtime. + public UserSettings(Serilog.Core.LoggingLevelSwitch loggingLevelSwitch) + { + this.InitializeComponent(); + this.lblMessage.Text = "User Settings"; + this.chkShowReleaseCandidates.Checked = Properties.Settings.Default.ShowReleaseCandidates; + this.chkShareStatistics.Checked = Properties.Settings.Default.ShareStatistics; + this.chkEnableLocalPackageInstall.Checked = Properties.Settings.Default.EnableLocalPackageInstall; + this.loggingLevelSwitch = loggingLevelSwitch; + this.PopulateLoggingLevelSwitchCombo(); + } + + /// + /// Gets a value indicating whether the user wants to display release candidates. + /// + public bool ShowReleaseCandidates => this.chkShowReleaseCandidates.Checked; + + /// + /// Gets a value indicating whether the user wants to share statistics. + /// + public bool ShareStatistics => this.chkShareStatistics.Checked; + + /// + /// Gets a value indicating whether the user wants to enable local package install. + /// + public bool EnableLocalPackageInstall => this.chkEnableLocalPackageInstall.Checked; + + private void PopulateLoggingLevelSwitchCombo() + { + this.cboLoggingLevel.Items.Clear(); + var levels = Enum.GetValues(typeof(LogEventLevel)).Cast(); + foreach (var level in levels) + { + this.cboLoggingLevel.Items.Add(level); + } + + this.cboLoggingLevel.SelectedItem = this.loggingLevelSwitch.MinimumLevel; + this.cboLoggingLevel.SelectedValueChanged += this.CboLogginLevel_SelectedValueChanged; + } + + private void CboLogginLevel_SelectedValueChanged(object sender, EventArgs e) + { + var cbo = (MetroComboBox)sender; + var newLevel = (LogEventLevel)cbo.SelectedItem; + + // To log information about the level change we must: + // 1. Force the level to Information (in case the level was set lower and it would not log information) + // 2. Log information about the level change + // 3. Change the level. + this.loggingLevelSwitch.MinimumLevel = LogEventLevel.Information; + Log.Logger.Information("Logging level changed to {newLevel}", newLevel); + this.loggingLevelSwitch.MinimumLevel = newLevel; + } + + private void lnkViewLogs_Click(object sender, EventArgs e) + { + var logsPath = Path.Combine(Environment.CurrentDirectory, "Logs"); + Process.Start("explorer.exe", logsPath); + } + + private void logsIcon_Click(object sender, EventArgs e) + { + var logsPath = Path.Combine(Environment.CurrentDirectory, "Logs"); + Process.Start("explorer.exe", logsPath); + } + } +} diff --git a/nvQuickSite/Controls/Settings/UserSettings.resx b/nvQuickSite/Controls/Settings/UserSettings.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/nvQuickSite/Controls/Settings/UserSettings.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/nvQuickSite/Controls/Sites/DeleteSiteProgress.Designer.cs b/nvQuickSite/Controls/Sites/DeleteSiteProgress.Designer.cs new file mode 100644 index 00000000..641a3b7b --- /dev/null +++ b/nvQuickSite/Controls/Sites/DeleteSiteProgress.Designer.cs @@ -0,0 +1,291 @@ +namespace nvQuickSite.Controls.Sites +{ + partial class DeleteSiteProgress + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.lblMessage = new MetroFramework.Controls.MetroLabel(); + this.progressTotal = new MetroFramework.Controls.MetroProgressBar(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.progressDeleteAppPool = new MetroFramework.Controls.MetroProgressBar(); + this.label7 = new System.Windows.Forms.Label(); + this.progressDeletingSite = new MetroFramework.Controls.MetroProgressBar(); + this.label6 = new System.Windows.Forms.Label(); + this.progressRemoveHostEntry = new MetroFramework.Controls.MetroProgressBar(); + this.label5 = new System.Windows.Forms.Label(); + this.progressDeleteFiles = new MetroFramework.Controls.MetroProgressBar(); + this.label4 = new System.Windows.Forms.Label(); + this.progressDeleteDatabae = new MetroFramework.Controls.MetroProgressBar(); + this.label3 = new System.Windows.Forms.Label(); + this.progressStopSite = new MetroFramework.Controls.MetroProgressBar(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.progressStopAppPool = new MetroFramework.Controls.MetroProgressBar(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // lblMessage + // + this.lblMessage.AutoSize = true; + this.lblMessage.Dock = System.Windows.Forms.DockStyle.Top; + this.lblMessage.FontSize = MetroFramework.MetroLabelSize.Tall; + this.lblMessage.FontWeight = MetroFramework.MetroLabelWeight.Bold; + this.lblMessage.Location = new System.Drawing.Point(20, 30); + this.lblMessage.Name = "lblMessage"; + this.lblMessage.Size = new System.Drawing.Size(104, 25); + this.lblMessage.Style = MetroFramework.MetroColorStyle.Blue; + this.lblMessage.TabIndex = 0; + this.lblMessage.Text = "Delete Site"; + this.lblMessage.UseStyleColors = true; + // + // progressTotal + // + this.progressTotal.Dock = System.Windows.Forms.DockStyle.Bottom; + this.progressTotal.HideProgressText = false; + this.progressTotal.Location = new System.Drawing.Point(20, 279); + this.progressTotal.Name = "progressTotal"; + this.progressTotal.Size = new System.Drawing.Size(530, 23); + this.progressTotal.Style = MetroFramework.MetroColorStyle.Blue; + this.progressTotal.TabIndex = 1; + this.progressTotal.Theme = MetroFramework.MetroThemeStyle.Light; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.progressDeleteAppPool, 1, 6); + this.tableLayoutPanel1.Controls.Add(this.label7, 0, 6); + this.tableLayoutPanel1.Controls.Add(this.progressDeletingSite, 1, 5); + this.tableLayoutPanel1.Controls.Add(this.label6, 0, 5); + this.tableLayoutPanel1.Controls.Add(this.progressRemoveHostEntry, 1, 4); + this.tableLayoutPanel1.Controls.Add(this.label5, 0, 4); + this.tableLayoutPanel1.Controls.Add(this.progressDeleteFiles, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.label4, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.progressDeleteDatabae, 1, 2); + this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.progressStopSite, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.label2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.progressStopAppPool, 1, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(20, 55); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 7; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(530, 224); + this.tableLayoutPanel1.TabIndex = 2; + // + // progressDeleteAppPool + // + this.progressDeleteAppPool.Dock = System.Windows.Forms.DockStyle.Top; + this.progressDeleteAppPool.Location = new System.Drawing.Point(116, 177); + this.progressDeleteAppPool.Name = "progressDeleteAppPool"; + this.progressDeleteAppPool.Size = new System.Drawing.Size(418, 23); + this.progressDeleteAppPool.TabIndex = 13; + // + // label7 + // + this.label7.AutoSize = true; + this.label7.Dock = System.Windows.Forms.DockStyle.Top; + this.label7.Location = new System.Drawing.Point(3, 182); + this.label7.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label7.Name = "label7"; + this.label7.Size = new System.Drawing.Size(107, 13); + this.label7.TabIndex = 12; + this.label7.Text = "Deleting AppPool"; + this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // progressDeletingSite + // + this.progressDeletingSite.Dock = System.Windows.Forms.DockStyle.Top; + this.progressDeletingSite.Location = new System.Drawing.Point(116, 148); + this.progressDeletingSite.Name = "progressDeletingSite"; + this.progressDeletingSite.Size = new System.Drawing.Size(418, 23); + this.progressDeletingSite.TabIndex = 11; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Dock = System.Windows.Forms.DockStyle.Top; + this.label6.Location = new System.Drawing.Point(3, 153); + this.label6.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(107, 13); + this.label6.TabIndex = 10; + this.label6.Text = "Deleting Site"; + this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // progressRemoveHostEntry + // + this.progressRemoveHostEntry.Dock = System.Windows.Forms.DockStyle.Top; + this.progressRemoveHostEntry.Location = new System.Drawing.Point(116, 119); + this.progressRemoveHostEntry.Name = "progressRemoveHostEntry"; + this.progressRemoveHostEntry.Size = new System.Drawing.Size(418, 23); + this.progressRemoveHostEntry.TabIndex = 9; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Dock = System.Windows.Forms.DockStyle.Top; + this.label5.Location = new System.Drawing.Point(3, 124); + this.label5.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(107, 13); + this.label5.TabIndex = 8; + this.label5.Text = "Removing Host Entry"; + this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // progressDeleteFiles + // + this.progressDeleteFiles.Dock = System.Windows.Forms.DockStyle.Top; + this.progressDeleteFiles.Location = new System.Drawing.Point(116, 90); + this.progressDeleteFiles.Name = "progressDeleteFiles"; + this.progressDeleteFiles.Size = new System.Drawing.Size(418, 23); + this.progressDeleteFiles.TabIndex = 7; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Dock = System.Windows.Forms.DockStyle.Top; + this.label4.Location = new System.Drawing.Point(3, 95); + this.label4.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(107, 13); + this.label4.TabIndex = 6; + this.label4.Text = "Deleting Files"; + this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // progressDeleteDatabae + // + this.progressDeleteDatabae.Dock = System.Windows.Forms.DockStyle.Top; + this.progressDeleteDatabae.Location = new System.Drawing.Point(116, 61); + this.progressDeleteDatabae.Name = "progressDeleteDatabae"; + this.progressDeleteDatabae.Size = new System.Drawing.Size(418, 23); + this.progressDeleteDatabae.TabIndex = 5; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Dock = System.Windows.Forms.DockStyle.Top; + this.label3.Location = new System.Drawing.Point(3, 66); + this.label3.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(107, 13); + this.label3.TabIndex = 4; + this.label3.Text = "Deleting Database"; + this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // progressStopSite + // + this.progressStopSite.Dock = System.Windows.Forms.DockStyle.Top; + this.progressStopSite.Location = new System.Drawing.Point(116, 3); + this.progressStopSite.Name = "progressStopSite"; + this.progressStopSite.Size = new System.Drawing.Size(418, 23); + this.progressStopSite.TabIndex = 3; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Dock = System.Windows.Forms.DockStyle.Top; + this.label2.Location = new System.Drawing.Point(3, 8); + this.label2.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(107, 13); + this.label2.TabIndex = 2; + this.label2.Text = "Stopping Site"; + this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(3, 37); + this.label1.Margin = new System.Windows.Forms.Padding(3, 8, 3, 0); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(107, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Stopping AppPool"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // progressStopAppPool + // + this.progressStopAppPool.Dock = System.Windows.Forms.DockStyle.Top; + this.progressStopAppPool.Location = new System.Drawing.Point(116, 32); + this.progressStopAppPool.Name = "progressStopAppPool"; + this.progressStopAppPool.Size = new System.Drawing.Size(418, 23); + this.progressStopAppPool.TabIndex = 1; + // + // DeleteSiteProgress + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BorderStyle = MetroFramework.Drawing.MetroBorderStyle.FixedSingle; + this.ClientSize = new System.Drawing.Size(570, 322); + this.Controls.Add(this.tableLayoutPanel1); + this.Controls.Add(this.progressTotal); + this.Controls.Add(this.lblMessage); + this.DisplayHeader = false; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "DeleteSiteProgress"; + this.Padding = new System.Windows.Forms.Padding(20, 30, 20, 20); + this.Resizable = false; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MetroFramework.Controls.MetroLabel lblMessage; + private MetroFramework.Controls.MetroProgressBar progressTotal; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Label label1; + private MetroFramework.Controls.MetroProgressBar progressStopAppPool; + private MetroFramework.Controls.MetroProgressBar progressStopSite; + private System.Windows.Forms.Label label2; + private MetroFramework.Controls.MetroProgressBar progressDeleteDatabae; + private System.Windows.Forms.Label label3; + private MetroFramework.Controls.MetroProgressBar progressDeleteFiles; + private System.Windows.Forms.Label label4; + private MetroFramework.Controls.MetroProgressBar progressRemoveHostEntry; + private System.Windows.Forms.Label label5; + private MetroFramework.Controls.MetroProgressBar progressDeletingSite; + private System.Windows.Forms.Label label6; + private MetroFramework.Controls.MetroProgressBar progressDeleteAppPool; + private System.Windows.Forms.Label label7; + } +} \ No newline at end of file diff --git a/nvQuickSite/Controls/Sites/DeleteSiteProgress.cs b/nvQuickSite/Controls/Sites/DeleteSiteProgress.cs new file mode 100644 index 00000000..33237623 --- /dev/null +++ b/nvQuickSite/Controls/Sites/DeleteSiteProgress.cs @@ -0,0 +1,242 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controls.Sites +{ + using System; + using System.Diagnostics.Contracts; + using System.Drawing; + using System.IO; + using System.Threading; + using System.Threading.Tasks; + using System.Windows.Forms; + + using MetroFramework.Forms; + using Microsoft.Web.Administration; + using nvQuickSite.Controllers; + + /// + /// Implementes the user specific settings form. + /// + public partial class DeleteSiteProgress : MetroForm + { + private readonly Site site; + private readonly string sitePath; + + /// + /// Initializes a new instance of the class. + /// + /// The site to delete. + public DeleteSiteProgress(Site site) + { + Contract.Requires(site != null); + + this.site = site; + this.sitePath = site.Applications[0].VirtualDirectories[0].PhysicalPath; + + this.InitializeComponent(); + + this.InitProgressBars(); + this.DeleteSite(); + } + + private void InitProgressBars() + { + var max = FileSystemController.CountFilesAndDirectories(this.sitePath); + if (max > 0) + { + this.progressDeleteFiles.Maximum = max; + } + + this.UpdateTotalProgress(); + } + + private async void DeleteSite() + { + using (var iisManager = new ServerManager()) + { + // Stop Site + var stopSiteProgress = new Progress(percent => + { + this.progressStopSite.Value = percent; + this.UpdateTotalProgress(); + }); + try + { + await Task.Run(() => IISController.StopSite(this.site.Id, stopSiteProgress)).ConfigureAwait(true); + } + catch (ArgumentException ex) + { + this.Abort(ex.Source, ex.Message); + } + + // Stop AppPool + var stopAppPoolProgress = new Progress(percent => + { + this.progressStopAppPool.Value = percent; + this.UpdateTotalProgress(); + }); + try + { + await Task.Run(() => IISController.StopAppPool(this.site.Id, stopAppPoolProgress)).ConfigureAwait(true); + } + catch (ArgumentException ex) + { + this.Abort(ex.Source, ex.Message); + } + + // Delete Database + var deleteDatabaseProgress = new Progress(percent => + { + this.progressDeleteDatabae.Value = percent; + this.UpdateTotalProgress(); + }); + try + { + var installFolder = Directory.GetParent(this.sitePath); + var databaseController = new DatabaseController( + this.site.Name.Split('.')[0], + Properties.Settings.Default.DatabaseServerNameRecent, + true, + string.Empty, + string.Empty, + installFolder.FullName, + true, + this.site.Name); + await Task.Run(() => databaseController.DeleteDatabase(deleteDatabaseProgress)).ConfigureAwait(true); + } + catch (ArgumentException ex) + { + this.Abort(ex.Source, ex.Message); + throw; + } + + // Delete files + var deleteFilesProgress = new Progress(name => + { + if (this.progressDeleteFiles.Value < this.progressDeleteFiles.Maximum) + { + this.progressDeleteFiles.Value++; + this.UpdateTotalProgress(); + } + }); + try + { + await Task.Run(() => FileSystemController.DeleteDirectory(this.sitePath, deleteFilesProgress, true)).ConfigureAwait(true); + } + catch (IOException) + { + // Files mights still be streaming (logs for instance) after the site is stopped and deleted. Let's wait a bit and retry once after waiting 10 seconds. + Thread.Sleep(10000); + await Task.Run(() => FileSystemController.DeleteDirectory(this.sitePath, deleteFilesProgress, true)).ConfigureAwait(true); + } + + this.progressDeleteFiles.Value = this.progressDeleteFiles.Maximum; + this.UpdateTotalProgress(); + + // Delete entry from HOSTS file + var deleteHostEntryProgress = new Progress(percent => + { + this.progressRemoveHostEntry.Value = percent; + this.UpdateTotalProgress(); + }); + await Task.Run(() => FileSystemController.RemoveHostEntry(this.site.Name, deleteHostEntryProgress)).ConfigureAwait(true); + + // Delete Site + var deleteSiteProgress = new Progress(percent => + { + this.progressDeletingSite.Value = percent; + this.UpdateTotalProgress(); + }); + try + { + await Task.Run(() => IISController.DeleteSite(this.site.Id, deleteSiteProgress)).ConfigureAwait(true); + } + catch (ArgumentException ex) + { + this.Abort(ex.Source, ex.Message); + } + + // Try to delete AppPool if possible + var deleteAppPoolProgress = new Progress(percent => + { + this.progressDeleteAppPool.Value = percent; + this.UpdateTotalProgress(); + }); + try + { + await Task.Run(() => IISController.DeleteAppPool(this.site.ApplicationDefaults.ApplicationPoolName, deleteAppPoolProgress)).ConfigureAwait(true); + } + catch (ArgumentException ex) + { + DialogController.ShowMessage( + ex.Source, + ex.Message, + SystemIcons.Error, + DialogController.DialogButtons.OK); + } + } + + this.progressTotal.Value = this.progressTotal.Maximum; + + DialogController.ShowMessage( + "Site Deleted", + $"{this.site.Name} has been deleted successfully.", + SystemIcons.Information, + DialogController.DialogButtons.OK); + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void UpdateTotalProgress() + { + this.progressTotal.Maximum = + this.progressStopAppPool.Maximum + + this.progressStopSite.Maximum + + this.progressDeleteDatabae.Maximum + + this.progressDeleteFiles.Maximum + + this.progressRemoveHostEntry.Maximum + + this.progressDeletingSite.Maximum + + this.progressDeleteAppPool.Maximum; + + var totalValue = + this.progressStopAppPool.Value + + this.progressStopSite.Value + + this.progressDeleteDatabae.Value + + this.progressDeleteFiles.Value + + this.progressRemoveHostEntry.Value + + this.progressDeleteAppPool.Value; + + if (this.progressTotal.Value < this.progressTotal.Maximum) + { + this.progressTotal.Value = totalValue; + } + } + + private void Abort(string errorTitle, string errorDescription) + { + DialogController.ShowMessage( + errorTitle, + errorDescription, + SystemIcons.Error, + DialogController.DialogButtons.OK); + + this.DialogResult = DialogResult.OK; + this.Close(); + } + } +} diff --git a/nvQuickSite/Controls/Sites/DeleteSiteProgress.resx b/nvQuickSite/Controls/Sites/DeleteSiteProgress.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/nvQuickSite/Controls/Sites/DeleteSiteProgress.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/nvQuickSite/Controls/Sites/ViewExistingSites.Designer.cs b/nvQuickSite/Controls/Sites/ViewExistingSites.Designer.cs new file mode 100644 index 00000000..32def01f --- /dev/null +++ b/nvQuickSite/Controls/Sites/ViewExistingSites.Designer.cs @@ -0,0 +1,175 @@ +namespace nvQuickSite.Controls.Sites +{ + partial class ViewExistingSites + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); + this.lblMessage = new MetroFramework.Controls.MetroLabel(); + this.metroButton2 = new MetroFramework.Controls.MetroButton(); + this.dataGridViewSites = new System.Windows.Forms.DataGridView(); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel2 = new System.Windows.Forms.Panel(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridViewSites)).BeginInit(); + this.panel1.SuspendLayout(); + this.panel2.SuspendLayout(); + this.SuspendLayout(); + // + // lblMessage + // + this.lblMessage.AutoSize = true; + this.lblMessage.Dock = System.Windows.Forms.DockStyle.Top; + this.lblMessage.FontSize = MetroFramework.MetroLabelSize.Tall; + this.lblMessage.FontWeight = MetroFramework.MetroLabelWeight.Bold; + this.lblMessage.Location = new System.Drawing.Point(20, 30); + this.lblMessage.Name = "lblMessage"; + this.lblMessage.Size = new System.Drawing.Size(124, 25); + this.lblMessage.Style = MetroFramework.MetroColorStyle.Blue; + this.lblMessage.TabIndex = 0; + this.lblMessage.Text = "Existing Sites"; + this.lblMessage.UseStyleColors = true; + // + // metroButton2 + // + this.metroButton2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.metroButton2.Cursor = System.Windows.Forms.Cursors.Hand; + this.metroButton2.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.metroButton2.Dock = System.Windows.Forms.DockStyle.Right; + this.metroButton2.Location = new System.Drawing.Point(752, 0); + this.metroButton2.Name = "metroButton2"; + this.metroButton2.Size = new System.Drawing.Size(70, 32); + this.metroButton2.TabIndex = 2; + this.metroButton2.Text = "Cancel"; + // + // dataGridViewSites + // + this.dataGridViewSites.AllowUserToAddRows = false; + this.dataGridViewSites.AllowUserToDeleteRows = false; + this.dataGridViewSites.AllowUserToResizeColumns = false; + this.dataGridViewSites.AllowUserToResizeRows = false; + dataGridViewCellStyle1.BackColor = System.Drawing.Color.WhiteSmoke; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.Color.DeepSkyBlue; + this.dataGridViewSites.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1; + this.dataGridViewSites.BackgroundColor = System.Drawing.Color.White; + this.dataGridViewSites.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.dataGridViewSites.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None; + this.dataGridViewSites.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single; + dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle2.BackColor = System.Drawing.Color.DeepSkyBlue; + dataGridViewCellStyle2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.SelectionBackColor = System.Drawing.Color.DeepSkyBlue; + dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.dataGridViewSites.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle2; + this.dataGridViewSites.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridViewSites.Cursor = System.Windows.Forms.Cursors.Hand; + dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle3.Padding = new System.Windows.Forms.Padding(5); + dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewSites.DefaultCellStyle = dataGridViewCellStyle3; + this.dataGridViewSites.Dock = System.Windows.Forms.DockStyle.Fill; + this.dataGridViewSites.EnableHeadersVisualStyles = false; + this.dataGridViewSites.GridColor = System.Drawing.SystemColors.Window; + this.dataGridViewSites.Location = new System.Drawing.Point(0, 10); + this.dataGridViewSites.Margin = new System.Windows.Forms.Padding(30, 120, 30, 50); + this.dataGridViewSites.MultiSelect = false; + this.dataGridViewSites.Name = "dataGridViewSites"; + this.dataGridViewSites.ReadOnly = true; + this.dataGridViewSites.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None; + this.dataGridViewSites.RowHeadersVisible = false; + this.dataGridViewSites.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing; + dataGridViewCellStyle4.Padding = new System.Windows.Forms.Padding(5); + this.dataGridViewSites.RowsDefaultCellStyle = dataGridViewCellStyle4; + this.dataGridViewSites.RowTemplate.DefaultCellStyle.SelectionBackColor = System.Drawing.Color.DarkGray; + this.dataGridViewSites.RowTemplate.DefaultCellStyle.SelectionForeColor = System.Drawing.Color.White; + this.dataGridViewSites.RowTemplate.Height = 32; + this.dataGridViewSites.RowTemplate.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewSites.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; + this.dataGridViewSites.ShowCellErrors = false; + this.dataGridViewSites.ShowCellToolTips = false; + this.dataGridViewSites.ShowEditingIcon = false; + this.dataGridViewSites.ShowRowErrors = false; + this.dataGridViewSites.Size = new System.Drawing.Size(822, 471); + this.dataGridViewSites.TabIndex = 3; + // + // panel1 + // + this.panel1.Controls.Add(this.metroButton2); + this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom; + this.panel1.Location = new System.Drawing.Point(20, 546); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(822, 32); + this.panel1.TabIndex = 4; + // + // panel2 + // + this.panel2.Controls.Add(this.dataGridViewSites); + this.panel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel2.Location = new System.Drawing.Point(20, 55); + this.panel2.Name = "panel2"; + this.panel2.Padding = new System.Windows.Forms.Padding(0, 10, 0, 10); + this.panel2.Size = new System.Drawing.Size(822, 491); + this.panel2.TabIndex = 5; + // + // ViewExistingSites + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BorderStyle = MetroFramework.Drawing.MetroBorderStyle.FixedSingle; + this.ClientSize = new System.Drawing.Size(862, 598); + this.Controls.Add(this.panel2); + this.Controls.Add(this.panel1); + this.Controls.Add(this.lblMessage); + this.DisplayHeader = false; + this.Name = "ViewExistingSites"; + this.Padding = new System.Windows.Forms.Padding(20, 30, 20, 20); + ((System.ComponentModel.ISupportInitialize)(this.dataGridViewSites)).EndInit(); + this.panel1.ResumeLayout(false); + this.panel2.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MetroFramework.Controls.MetroLabel lblMessage; + private MetroFramework.Controls.MetroButton metroButton2; + private System.Windows.Forms.DataGridView dataGridViewSites; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Panel panel2; + } +} \ No newline at end of file diff --git a/nvQuickSite/Controls/Sites/ViewExistingSites.cs b/nvQuickSite/Controls/Sites/ViewExistingSites.cs new file mode 100644 index 00000000..915c3b7d --- /dev/null +++ b/nvQuickSite/Controls/Sites/ViewExistingSites.cs @@ -0,0 +1,125 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Controls.Sites +{ + using System.Diagnostics; + using System.Drawing; + using System.Globalization; + using System.Linq; + using System.Windows.Forms; + + using MetroFramework.Forms; + using Microsoft.Web.Administration; + using nvQuickSite.Controllers; + + /// + /// Implementes the user specific settings form. + /// + public partial class ViewExistingSites : MetroForm + { + private IOrderedEnumerable sites; + + /// + /// Initializes a new instance of the class. + /// + public ViewExistingSites() + { + this.InitializeComponent(); + this.BindViewSitesDataGrid(); + } + + private void BindViewSitesDataGrid() + { + this.sites = IISController.GetSites(true).OrderBy(s => s.Name); + using (var deleteButton = new DataGridViewButtonColumn()) + { + deleteButton.Text = "Delete"; + deleteButton.Name = "Delete"; + deleteButton.HeaderText = string.Empty; + + this.dataGridViewSites.AllowUserToDeleteRows = true; + this.dataGridViewSites.Columns.Clear(); + this.dataGridViewSites.Columns.Add(deleteButton); + this.dataGridViewSites.Columns.Add("Id", "ID"); + this.dataGridViewSites.Columns.Add(new DataGridViewLinkColumn() { Name = "SiteName", HeaderText = "Site Name" }); + this.dataGridViewSites.Columns.Add("ApplicationPool", "Application Pool"); + this.dataGridViewSites.Columns.Add("State", "State"); + this.dataGridViewSites.Columns.Add("Path", "Path"); + + this.dataGridViewSites.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; + this.dataGridViewSites.Columns["Id"].CellTemplate.Style.Alignment = DataGridViewContentAlignment.MiddleRight; + this.dataGridViewSites.Columns["Path"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; + } + + this.dataGridViewSites.Rows.Clear(); + foreach (var site in this.sites) + { + this.dataGridViewSites.Rows.Add( + "Delete", + site.Id, + site.Name, + site.ApplicationDefaults.ApplicationPoolName, + site.State.ToString(), + site.Applications["/"].VirtualDirectories["/"].PhysicalPath); + } + + this.dataGridViewSites.AutoResizeColumns(); + this.dataGridViewSites.CellContentClick += this.DataGridViewSites_CellContentClick; + } + + private void DataGridViewSites_CellContentClick(object sender, DataGridViewCellEventArgs e) + { + if (e.RowIndex < 0) + { + return; + } + + var row = this.dataGridViewSites.Rows[e.RowIndex]; + var column = this.dataGridViewSites.Columns[e.ColumnIndex]; + var id = int.Parse(row.Cells["Id"].Value.ToString(), CultureInfo.InvariantCulture); + var site = this.sites.FirstOrDefault(s => s.Id == id); + + if (column.Name == "Delete") + { + var result = DialogController.ShowMessage( + "Delete Site", + $"Are you sure you want to delete the following site?\n{site.Name}", + SystemIcons.Question, + DialogController.DialogButtons.YesNo); + + if (result == DialogResult.Yes) + { + using (var deleteSiteProgress = new DeleteSiteProgress(site)) + { + this.dataGridViewSites.CellContentClick -= this.DataGridViewSites_CellContentClick; + var deleteSiteResult = deleteSiteProgress.ShowDialog(); + if (deleteSiteResult == DialogResult.OK) + { + this.BindViewSitesDataGrid(); + } + } + } + } + + if (column.Name == "SiteName") + { + Process.Start($"{site.Bindings[0].Protocol}://{site.Bindings[0].Host}"); + } + } + } +} diff --git a/nvQuickSite/Controls/Sites/ViewExistingSites.resx b/nvQuickSite/Controls/Sites/ViewExistingSites.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/nvQuickSite/Controls/Sites/ViewExistingSites.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/nvQuickSite/Exceptions/ReadAndExtractException.cs b/nvQuickSite/Exceptions/ReadAndExtractException.cs new file mode 100644 index 00000000..fe792135 --- /dev/null +++ b/nvQuickSite/Exceptions/ReadAndExtractException.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +namespace nvQuickSite.Exceptions +{ + using System; + using System.Runtime.Serialization; + + /// + /// Thrown when an error occurs while tryint to read and extract a package. + /// + [Serializable] + public class ReadAndExtractException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public ReadAndExtractException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly message to display to the user. + public ReadAndExtractException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A friendly message to display to the user. + /// The details of the exception that triggered this exception. + public ReadAndExtractException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The serialization information. + /// The streaming context. + protected ReadAndExtractException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/nvQuickSite/Main.Designer.cs b/nvQuickSite/Main.Designer.cs index 37f2be4f..776a128d 100644 --- a/nvQuickSite/Main.Designer.cs +++ b/nvQuickSite/Main.Designer.cs @@ -30,11 +30,11 @@ private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main)); this.pictureBox2 = new System.Windows.Forms.PictureBox(); - this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.footerImageLink = new System.Windows.Forms.PictureBox(); this.lblVersion = new System.Windows.Forms.Label(); this.tileGetNewVersion = new MetroFramework.Controls.MetroTile(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.footerImageLink)).BeginInit(); this.SuspendLayout(); // // pictureBox2 @@ -47,16 +47,16 @@ private void InitializeComponent() this.pictureBox2.TabIndex = 1; this.pictureBox2.TabStop = false; // - // pictureBox1 + // footerImageLink // - this.pictureBox1.Cursor = System.Windows.Forms.Cursors.Hand; - this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image"))); - this.pictureBox1.Location = new System.Drawing.Point(26, 513); - this.pictureBox1.Name = "pictureBox1"; - this.pictureBox1.Size = new System.Drawing.Size(604, 55); - this.pictureBox1.TabIndex = 3; - this.pictureBox1.TabStop = false; - this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); + this.footerImageLink.Cursor = System.Windows.Forms.Cursors.Hand; + this.footerImageLink.Image = ((System.Drawing.Image)(resources.GetObject("footerImageLink.Image"))); + this.footerImageLink.Location = new System.Drawing.Point(26, 513); + this.footerImageLink.Name = "footerImageLink"; + this.footerImageLink.Size = new System.Drawing.Size(604, 55); + this.footerImageLink.TabIndex = 3; + this.footerImageLink.TabStop = false; + this.footerImageLink.Click += new System.EventHandler(this.footerImageLink_Click); // // lblVersion // @@ -93,15 +93,17 @@ private void InitializeComponent() this.ClientSize = new System.Drawing.Size(650, 580); this.Controls.Add(this.tileGetNewVersion); this.Controls.Add(this.lblVersion); - this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.footerImageLink); this.Controls.Add(this.pictureBox2); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximizeBox = false; + this.MinimizeBox = false; this.Name = "Main"; this.Resizable = false; this.Style = MetroFramework.MetroColorStyle.Blue; this.Theme = MetroFramework.MetroThemeStyle.Light; ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.footerImageLink)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -109,7 +111,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.PictureBox pictureBox2; - private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.PictureBox footerImageLink; private System.Windows.Forms.Label lblVersion; private MetroFramework.Controls.MetroTile tileGetNewVersion; } diff --git a/nvQuickSite/Main.cs b/nvQuickSite/Main.cs index 95749621..303d9497 100644 --- a/nvQuickSite/Main.cs +++ b/nvQuickSite/Main.cs @@ -1,76 +1,102 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using System; -using System.Windows.Forms; -using System.Diagnostics; -using System.Configuration; -using System.Linq; -using MetroFramework.Forms; -using Segment; -using JCS; -using nvQuickSite.Controllers; +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite { + using System; + using System.Diagnostics; + using System.Drawing; + using System.Globalization; + using System.Windows.Forms; + + using JCS; + using MetroFramework.Forms; + using nvQuickSite.Controllers; + using nvQuickSite.Controllers.Exceptions; + using Segment; + using Serilog; + using Serilog.Core; + + /// + /// Implements the logic of the main form. + /// public partial class Main : MetroForm { - public Main() + /// + /// Initializes a new instance of the class. + /// + /// An object that can be used to dynamically change the logging level at runtime. + public Main(LoggingLevelSwitch loggingLevelSwitch) { - InitializeComponent(); + this.InitializeComponent(); if (Properties.Settings.Default.UpdateSettings) { + Log.Logger.Information("Updating user settings per new release."); + Log.Logger.Debug("OLD user settings: {@settings}", Properties.Settings.Default); Properties.Settings.Default.Upgrade(); Properties.Settings.Default.UpdateSettings = false; Properties.Settings.Default.Save(); + Log.Logger.Debug("NEW user settings: {@settings}", Properties.Settings.Default); } + var osInfo = $"{OSVersionInfo.Name} {OSVersionInfo.Edition} {OSVersionInfo.ServicePack}"; + var versionString = OSVersionInfo.VersionString; + Log.Logger.Information("Operating System information: {osInfo} {versionString}", osInfo, versionString); if (Properties.Settings.Default.ShareStatistics) { - var userGuid = System.Guid.NewGuid().ToString("B").ToUpper(); + var userGuid = Guid.NewGuid().ToString("B").ToUpper(CultureInfo.InvariantCulture); Analytics.Initialize("pzNi0MJVC1P9tVZdnvDOyptvUwPov9BN", new Config().SetAsync(false)); - Analytics.Client.Track(userGuid, "Started App", new Segment.Model.Properties() { - //{ "datetime", DateTime.Now }, - { "dimension1", OSVersionInfo.Name + " " + OSVersionInfo.Edition + " " + OSVersionInfo.ServicePack } - }); + Analytics.Client.Track( + userGuid, + "Started App", + new Segment.Model.Properties() + { + { + "dimension1", + osInfo + }, + }); } - lblVersion.Text = "v" + Application.ProductVersion; + this.lblVersion.Text = "v" + Application.ProductVersion; - var latestVersion = VersionController.GetRemoteLatestVersion(); - if (Version.Parse(latestVersion) > Version.Parse(Application.ProductVersion)) + try + { + var latestVersion = VersionController.GetRemoteLatestVersion(); + if (Version.Parse(latestVersion) > Version.Parse(Application.ProductVersion)) + { + Log.Information("Version {version} is available.", latestVersion); + this.tileGetNewVersion.Visible = true; + } + } + catch (VersionControllerException ex) { - tileGetNewVersion.Visible = true; + DialogController.ShowMessage(ex.Source, ex.Message, SystemIcons.Error, DialogController.DialogButtons.OK); } - Start control = new Start(); + Start control = new Start(loggingLevelSwitch); control.Dock = DockStyle.Fill; - Controls.Add(control); - } - - private bool SettingExists(string settingName) - { - return Properties.Settings.Default.Properties.Cast().Any(prop => prop.Name == settingName); + this.Controls.Add(control); } - private void pictureBox1_Click(object sender, EventArgs e) + private void footerImageLink_Click(object sender, EventArgs e) { - Process.Start("http://www.nvisionative.com"); + Process.Start("http://www.nvisionative.com"); } private void tileGetNewVersion_Click(object sender, EventArgs e) diff --git a/nvQuickSite/Main.resx b/nvQuickSite/Main.resx index 4afaceda..9b30247d 100644 --- a/nvQuickSite/Main.resx +++ b/nvQuickSite/Main.resx @@ -217,7 +217,7 @@ cAa8F1R7zwvNB4gXTmvwd/Mnc6SppNThAAAAAElFTkSuQmCC - + iVBORw0KGgoAAAANSUhEUgAAAlcAAAAuCAYAAAAFiTykAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAABrnSURBVHhe7Z0L3F3TmcZPNO5FFcVQREJqxCURt6Sp diff --git a/nvQuickSite/Models/Package.cs b/nvQuickSite/Models/Package.cs index d031acaf..772e19a7 100644 --- a/nvQuickSite/Models/Package.cs +++ b/nvQuickSite/Models/Package.cs @@ -1,29 +1,63 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite.Models { + /// + /// Represents one package. + /// public class Package { + /// + /// Gets or sets the package distribution id. + /// public string did { get; set; } + + /// + /// Gets or sets the package name. + /// public string name { get; set; } + + /// + /// Gets or sets the package version. + /// public string version { get; set; } + + /// + /// Gets or sets the url to download the install package. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Design", + "CA1056:URI-like properties should not be strings", + Justification = "Needs to be a simple string for serialization.")] public string url { get; set; } + + /// + /// Gets or sets the url to download the upgrade package. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Design", + "CA1056:URI-like properties should not be strings", + Justification = "Needs to be a simple string for serialization.")] public string upgradeurl { get; set; } - public bool keep { get; set; } = false; + + /// + /// Gets or sets a value indicating whether to keep this package. + /// + public bool keep { get; set; } } -} \ No newline at end of file +} diff --git a/nvQuickSite/Models/Version.cs b/nvQuickSite/Models/Version.cs index fadcfa3b..c486eff8 100644 --- a/nvQuickSite/Models/Version.cs +++ b/nvQuickSite/Models/Version.cs @@ -1,24 +1,30 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite.Models { - class Version + /// + /// Represents a version model. + /// + public class Version { + /// + /// Gets or sets the latest version. + /// public string latestVersion { get; set; } } } diff --git a/nvQuickSite/MsgBoxYesNoIgnore.cs b/nvQuickSite/MsgBoxYesNoIgnore.cs deleted file mode 100644 index d3fbf31b..00000000 --- a/nvQuickSite/MsgBoxYesNoIgnore.cs +++ /dev/null @@ -1,42 +0,0 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using System.Drawing; -using MetroFramework.Forms; - -namespace nvQuickSite -{ - public partial class MsgBoxYesNoIgnore : MetroForm - { - public MsgBoxYesNoIgnore(bool doNotWarnAgain, string dialogMessage, Image dialogIconImage) - { - InitializeComponent(); - chkDoNotWarnAgain.Checked = doNotWarnAgain; - lblMessage.Text = dialogMessage; - dialogIcon.Image = dialogIconImage; - } - - public bool DoNotWarnAgain - { - get { return chkDoNotWarnAgain.Checked; } - } - - //public string DialogMessage { get; set; } - - //public Image DialogIcon { get; set; } - } -} diff --git a/nvQuickSite/Program.cs b/nvQuickSite/Program.cs index 710a6f78..38e80665 100644 --- a/nvQuickSite/Program.cs +++ b/nvQuickSite/Program.cs @@ -1,43 +1,63 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using System; -using System.Windows.Forms; -using System.Security.Principal; -using System.Diagnostics; +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite { - static class Program + using System; + using System.Diagnostics; + using System.Security.Principal; + using System.Windows.Forms; + + using Serilog; + using Serilog.Core; + + /// + /// Implements the program entry point. + /// + public static class Program { /// /// The main entry point for the application. /// [STAThread] - static void Main() + private static void Main() { + var loggingLevelSwitch = new LoggingLevelSwitch(); + var log = new LoggerConfiguration() + .MinimumLevel.ControlledBy(loggingLevelSwitch) + .WriteTo.File( + path: "Logs\\log-.txt", + rollingInterval: RollingInterval.Day) + .WriteTo.Console() + .WriteTo.Debug() + .CreateLogger(); + log.Information("Application Started v{version}", Application.ProductVersion); + Log.Logger = log; + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent()); + log.Debug("Current user is {@principal}", principal.Identity.Name); bool administrativeMode = principal.IsInRole(WindowsBuiltInRole.Administrator); if (!administrativeMode) { + log.Information("Starting as an administrator."); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.Verb = "runas"; startInfo.FileName = Application.ExecutablePath; @@ -47,13 +67,16 @@ static void Main() } catch { - return; + throw; } + return; } - Application.Run(new Main()); - + using (var main = new Main(loggingLevelSwitch)) + { + Application.Run(main); + } } } } diff --git a/nvQuickSite/Properties/AssemblyInfo.cs b/nvQuickSite/Properties/AssemblyInfo.cs index 6aa7d8e0..185ac9ce 100644 --- a/nvQuickSite/Properties/AssemblyInfo.cs +++ b/nvQuickSite/Properties/AssemblyInfo.cs @@ -1,7 +1,25 @@ -using System.Reflection; +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . + +using System.Reflection; +using System.Resources; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("nvQuickSite")] @@ -9,12 +27,12 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("nvisionative, Inc.")] [assembly: AssemblyProduct("nvQuickSite")] -[assembly: AssemblyCopyright("Copyright © 2016-2019 nvisionative, Inc.")] +[assembly: AssemblyCopyright("Copyright © 2016-2020 nvisionative, Inc.")] [assembly: AssemblyTrademark("TM")] [assembly: AssemblyCulture("")] -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] @@ -24,13 +42,13 @@ // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Build and Revision Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.4.2")] -[assembly: AssemblyFileVersion("1.4.2")] - \ No newline at end of file +[assembly: AssemblyVersion("2.0.0")] +[assembly: AssemblyFileVersion("2.0.0")] +[assembly: NeutralResourcesLanguage("en")] diff --git a/nvQuickSite/Properties/Resources.Designer.cs b/nvQuickSite/Properties/Resources.Designer.cs index 3db0fcbd..2f9eebb7 100644 --- a/nvQuickSite/Properties/Resources.Designer.cs +++ b/nvQuickSite/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace nvQuickSite.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -90,6 +90,16 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap logs_icon { + get { + object obj = ResourceManager.GetObject("logs-icon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/nvQuickSite/Properties/Resources.resx b/nvQuickSite/Properties/Resources.resx index 3692ed26..85fe44ed 100644 --- a/nvQuickSite/Properties/Resources.resx +++ b/nvQuickSite/Properties/Resources.resx @@ -124,10 +124,13 @@ ..\Resources\dnn_logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\user-settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\DNN_company_logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\user-settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\logs-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/nvQuickSite/Properties/Settings.Designer.cs b/nvQuickSite/Properties/Settings.Designer.cs index 2072a385..93971088 100644 --- a/nvQuickSite/Properties/Settings.Designer.cs +++ b/nvQuickSite/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace nvQuickSite.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -178,5 +178,29 @@ internal sealed partial class Settings : global::System.Configuration.Applicatio this["UpdateSettings"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DatabaseUserNameRecent { + get { + return ((string)(this["DatabaseUserNameRecent"])); + } + set { + this["DatabaseUserNameRecent"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool EnableLocalPackageInstall { + get { + return ((bool)(this["EnableLocalPackageInstall"])); + } + set { + this["EnableLocalPackageInstall"] = value; + } + } } } diff --git a/nvQuickSite/Properties/Settings.settings b/nvQuickSite/Properties/Settings.settings index 32274621..6098cfd0 100644 --- a/nvQuickSite/Properties/Settings.settings +++ b/nvQuickSite/Properties/Settings.settings @@ -41,5 +41,11 @@ True + + + + + False + \ No newline at end of file diff --git a/nvQuickSite/Resources/._logs-icon.png b/nvQuickSite/Resources/._logs-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..95cbc95f6ca9131af92f946259a13c35e35cddd5 GIT binary patch literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWxd1=+Gz%wBU!WKc z;207Tl=*1)a)=IwIY4FnXi6D@e5km1a(=E}VnIPps$NKHMTu)(a(+r?UOG@gX-S%{ zg|(rviIJhXrG*Ka5u@DE5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2^4FOPR z6NJG)E+iwfSfMDjIKQ+gIaMJozbIQFGp{5yuOu@+FEJ;lQXwZbtwbRyCowM@*cXQC R8qyT1|KVPdVUYX(9{>uvEyDl+ literal 0 HcmV?d00001 diff --git a/nvQuickSite/Resources/logs-icon.png b/nvQuickSite/Resources/logs-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a92a08c98c6757a84fc1c14cc1a45aa971b1e5d5 GIT binary patch literal 1134 zcmeAS@N?(olHy`uVBq!ia0vp^+(69F!3HFaY)uV-lw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6H#24>aFkcg59UmvUF{9L_6kQ%*;+ybC(1_m4Zih{)C?9>v4 zq}24xJX@vryZ0+8WTx0Eg`4^s_!c;)W@LI)6{QAO`Gq7`WhYyvDB0U7*i={n4aiL` zNmQuF&B-gas<2f8n`;GRgM{^!6u?SKvTcwn^Gtf;oFfdXux70H< zGcmES&`~flFf!0LFxNLU&^0o$GBC3;HCBKEC7^9ZDQQ+gE^bh}fIM5JjFOT9D}DX) z@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7^KE~&-IMVSR9nfZANAQKal z@=Hr>m4GgVcpE=kNwPW5!LRRS8KmzkMj<>+i- zVrp(~>SkhO1k>x1pIn-onpXnTn}X15iBm5qHRKimZFWg5$}CGwaVyHtRRH_iDie!a zOwEiffVR2;%`?I77Kq*yEN%hoH3Oy{Tzd6^j?o9jEmB;=gn$VM#Du3@AP1iIQ}cic zz6hAIed15u1LlhRo-U3d6}OVE-1+lOmsz=4fLSUbDdkMXuWySb)vaH%CdR!xS^xiE zazau^=m81uQkAwI9W?i)&dj=K>hClY6-#*X&oChiaJYD@< J);T3K0RVxgdISIf literal 0 HcmV?d00001 diff --git a/nvQuickSite/Settings.cs b/nvQuickSite/Settings.cs index 47fae06d..f408825e 100644 --- a/nvQuickSite/Settings.cs +++ b/nvQuickSite/Settings.cs @@ -1,43 +1,50 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -namespace nvQuickSite.Properties { - - // This class allows you to handle specific events on the settings class: - // The SettingChanging event is raised before a setting's value is changed. - // The PropertyChanged event is raised after a setting's value is changed. - // The SettingsLoaded event is raised after the setting values are loaded. - // The SettingsSaving event is raised before the setting values are saved. - internal sealed partial class Settings { - - public Settings() { - // // To add event handlers for saving and changing settings, uncomment the lines below: +namespace nvQuickSite.Properties +{ + /// + /// This class allows you to handle specific events on the settings class. + /// The SettingChanging event is raised before a setting's value is changed. + /// The PropertyChanged event is raised after a setting's value is changed. + /// The SettingsLoaded event is raised after the setting values are loaded. + /// The SettingsSaving event is raised before the setting values are saved. + /// + internal sealed partial class Settings + { + /// + /// Initializes a new instance of the class. + /// + public Settings() + { + // To add event handlers for saving and changing settings, uncomment the lines below: // // this.SettingChanging += this.SettingChangingEventHandler; // // this.SettingsSaving += this.SettingsSavingEventHandler; - // } - - private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { + + private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) + { // Add code to handle the SettingChangingEvent event here. } - - private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) { + + private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) + { // Add code to handle the SettingsSaving event here. } } diff --git a/nvQuickSite/Start.Designer.cs b/nvQuickSite/Start.Designer.cs index 0757d402..b9890447 100644 --- a/nvQuickSite/Start.Designer.cs +++ b/nvQuickSite/Start.Designer.cs @@ -51,7 +51,6 @@ private void InitializeComponent() this.lblLatestReleases = new MetroFramework.Controls.MetroLabel(); this.lblLocalInstallPackage = new MetroFramework.Controls.MetroLabel(); this.cboProductName = new MetroFramework.Controls.MetroComboBox(); - this.btnGetLatestRelease = new MetroFramework.Controls.MetroButton(); this.btnViewAllReleases = new MetroFramework.Controls.MetroButton(); this.tabControl = new MetroFramework.Controls.MetroTabControl(); this.tabDatabaseInfo = new MetroFramework.Controls.MetroTabPage(); @@ -76,8 +75,9 @@ private void InitializeComponent() this.tileDNNDocs = new MetroFramework.Controls.MetroTile(); this.tileMorenvQuickProducts = new MetroFramework.Controls.MetroTile(); this.lblRemember = new MetroFramework.Controls.MetroLabel(); - this.tileQuickSettings = new MetroFramework.Controls.MetroTile(); this.tileDNNCommunity = new MetroFramework.Controls.MetroTile(); + this.btnViewExistingSites = new MetroFramework.Controls.MetroButton(); + this.tileQuickSettings = new MetroFramework.Controls.MetroTile(); this.tabSiteInfo.SuspendLayout(); this.tabInstallPackage.SuspendLayout(); this.tabControl.SuspendLayout(); @@ -100,21 +100,17 @@ private void InitializeComponent() this.tabSiteInfo.Controls.Add(this.lblSiteName); this.tabSiteInfo.Controls.Add(this.txtSiteNamePrefix); this.tabSiteInfo.HorizontalScrollbarBarColor = true; - this.tabSiteInfo.HorizontalScrollbarSize = 19; - this.tabSiteInfo.Location = new System.Drawing.Point(8, 42); - this.tabSiteInfo.Margin = new System.Windows.Forms.Padding(6); + this.tabSiteInfo.Location = new System.Drawing.Point(4, 35); this.tabSiteInfo.Name = "tabSiteInfo"; - this.tabSiteInfo.Size = new System.Drawing.Size(1198, 515); + this.tabSiteInfo.Size = new System.Drawing.Size(599, 255); this.tabSiteInfo.TabIndex = 1; this.tabSiteInfo.Text = "Site Info"; this.tabSiteInfo.VerticalScrollbarBarColor = true; - this.tabSiteInfo.VerticalScrollbarSize = 20; // // lblInstallSubFolder // this.lblInstallSubFolder.AutoSize = true; - this.lblInstallSubFolder.Location = new System.Drawing.Point(646, 277); - this.lblInstallSubFolder.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblInstallSubFolder.Location = new System.Drawing.Point(323, 144); this.lblInstallSubFolder.Name = "lblInstallSubFolder"; this.lblInstallSubFolder.Size = new System.Drawing.Size(109, 19); this.lblInstallSubFolder.TabIndex = 14; @@ -122,50 +118,48 @@ private void InitializeComponent() // // txtInstallSubFolder // - this.txtInstallSubFolder.Location = new System.Drawing.Point(646, 325); - this.txtInstallSubFolder.Margin = new System.Windows.Forms.Padding(6); + this.txtInstallSubFolder.Location = new System.Drawing.Point(323, 169); this.txtInstallSubFolder.Name = "txtInstallSubFolder"; - this.txtInstallSubFolder.Size = new System.Drawing.Size(434, 44); + this.txtInstallSubFolder.Size = new System.Drawing.Size(217, 23); this.txtInstallSubFolder.TabIndex = 13; // // txtSiteNameSuffix // this.txtSiteNameSuffix.FontWeight = MetroFramework.MetroTextBoxWeight.Light; - this.txtSiteNameSuffix.Location = new System.Drawing.Point(646, 71); - this.txtSiteNameSuffix.Margin = new System.Windows.Forms.Padding(6); + this.txtSiteNameSuffix.Location = new System.Drawing.Point(323, 37); this.txtSiteNameSuffix.Name = "txtSiteNameSuffix"; - this.txtSiteNameSuffix.Size = new System.Drawing.Size(434, 44); + this.txtSiteNameSuffix.Size = new System.Drawing.Size(217, 23); this.txtSiteNameSuffix.TabIndex = 12; this.txtSiteNameSuffix.Text = ".dnndev.me"; // // btnSiteInfoBack // - this.btnSiteInfoBack.Location = new System.Drawing.Point(0, 413); - this.btnSiteInfoBack.Margin = new System.Windows.Forms.Padding(6); + this.btnSiteInfoBack.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnSiteInfoBack.Location = new System.Drawing.Point(0, 215); this.btnSiteInfoBack.Name = "btnSiteInfoBack"; - this.btnSiteInfoBack.Size = new System.Drawing.Size(180, 69); + this.btnSiteInfoBack.Size = new System.Drawing.Size(90, 36); this.btnSiteInfoBack.TabIndex = 11; this.btnSiteInfoBack.Text = "&Back"; this.btnSiteInfoBack.Click += new System.EventHandler(this.btnSiteInfoBack_Click); // // btnSiteInfoNext // + this.btnSiteInfoNext.Cursor = System.Windows.Forms.Cursors.Hand; this.btnSiteInfoNext.Highlight = true; - this.btnSiteInfoNext.Location = new System.Drawing.Point(1014, 415); - this.btnSiteInfoNext.Margin = new System.Windows.Forms.Padding(6); + this.btnSiteInfoNext.Location = new System.Drawing.Point(507, 216); this.btnSiteInfoNext.Name = "btnSiteInfoNext"; - this.btnSiteInfoNext.Size = new System.Drawing.Size(180, 69); + this.btnSiteInfoNext.Size = new System.Drawing.Size(90, 36); this.btnSiteInfoNext.TabIndex = 10; this.btnSiteInfoNext.Text = "&Next"; this.btnSiteInfoNext.Click += new System.EventHandler(this.btnSiteInfoNext_Click); // // btnLocation // + this.btnLocation.Cursor = System.Windows.Forms.Cursors.Hand; this.btnLocation.Highlight = true; - this.btnLocation.Location = new System.Drawing.Point(556, 325); - this.btnLocation.Margin = new System.Windows.Forms.Padding(6); + this.btnLocation.Location = new System.Drawing.Point(278, 169); this.btnLocation.Name = "btnLocation"; - this.btnLocation.Size = new System.Drawing.Size(76, 44); + this.btnLocation.Size = new System.Drawing.Size(38, 23); this.btnLocation.Style = MetroFramework.MetroColorStyle.Blue; this.btnLocation.TabIndex = 8; this.btnLocation.Text = "..."; @@ -174,8 +168,7 @@ private void InitializeComponent() // lblInstallBaseFolder // this.lblInstallBaseFolder.AutoSize = true; - this.lblInstallBaseFolder.Location = new System.Drawing.Point(0, 277); - this.lblInstallBaseFolder.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblInstallBaseFolder.Location = new System.Drawing.Point(0, 144); this.lblInstallBaseFolder.Name = "lblInstallBaseFolder"; this.lblInstallBaseFolder.Size = new System.Drawing.Size(114, 19); this.lblInstallBaseFolder.TabIndex = 7; @@ -184,10 +177,9 @@ private void InitializeComponent() // txtInstallBaseFolder // this.txtInstallBaseFolder.FontWeight = MetroFramework.MetroTextBoxWeight.Light; - this.txtInstallBaseFolder.Location = new System.Drawing.Point(0, 325); - this.txtInstallBaseFolder.Margin = new System.Windows.Forms.Padding(6); + this.txtInstallBaseFolder.Location = new System.Drawing.Point(0, 169); this.txtInstallBaseFolder.Name = "txtInstallBaseFolder"; - this.txtInstallBaseFolder.Size = new System.Drawing.Size(544, 44); + this.txtInstallBaseFolder.Size = new System.Drawing.Size(272, 23); this.txtInstallBaseFolder.TabIndex = 6; // // chkDeleteSiteIfExists @@ -195,8 +187,7 @@ private void InitializeComponent() this.chkDeleteSiteIfExists.AutoSize = true; this.chkDeleteSiteIfExists.Checked = true; this.chkDeleteSiteIfExists.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkDeleteSiteIfExists.Location = new System.Drawing.Point(0, 217); - this.chkDeleteSiteIfExists.Margin = new System.Windows.Forms.Padding(6); + this.chkDeleteSiteIfExists.Location = new System.Drawing.Point(0, 113); this.chkDeleteSiteIfExists.Name = "chkDeleteSiteIfExists"; this.chkDeleteSiteIfExists.Size = new System.Drawing.Size(156, 15); this.chkDeleteSiteIfExists.TabIndex = 5; @@ -208,8 +199,7 @@ private void InitializeComponent() this.chkSiteSpecificAppPool.AutoSize = true; this.chkSiteSpecificAppPool.Checked = true; this.chkSiteSpecificAppPool.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkSiteSpecificAppPool.Location = new System.Drawing.Point(0, 158); - this.chkSiteSpecificAppPool.Margin = new System.Windows.Forms.Padding(6); + this.chkSiteSpecificAppPool.Location = new System.Drawing.Point(0, 82); this.chkSiteSpecificAppPool.Name = "chkSiteSpecificAppPool"; this.chkSiteSpecificAppPool.Size = new System.Drawing.Size(303, 15); this.chkSiteSpecificAppPool.TabIndex = 4; @@ -219,8 +209,7 @@ private void InitializeComponent() // lblSiteName // this.lblSiteName.AutoSize = true; - this.lblSiteName.Location = new System.Drawing.Point(0, 23); - this.lblSiteName.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblSiteName.Location = new System.Drawing.Point(0, 12); this.lblSiteName.Name = "lblSiteName"; this.lblSiteName.Size = new System.Drawing.Size(105, 19); this.lblSiteName.TabIndex = 3; @@ -229,10 +218,9 @@ private void InitializeComponent() // txtSiteNamePrefix // this.txtSiteNamePrefix.FontWeight = MetroFramework.MetroTextBoxWeight.Light; - this.txtSiteNamePrefix.Location = new System.Drawing.Point(0, 71); - this.txtSiteNamePrefix.Margin = new System.Windows.Forms.Padding(6); + this.txtSiteNamePrefix.Location = new System.Drawing.Point(0, 37); this.txtSiteNamePrefix.Name = "txtSiteNamePrefix"; - this.txtSiteNamePrefix.Size = new System.Drawing.Size(632, 44); + this.txtSiteNamePrefix.Size = new System.Drawing.Size(316, 23); this.txtSiteNamePrefix.TabIndex = 2; this.txtSiteNamePrefix.Text = "MySite"; this.txtSiteNamePrefix.UseStyleColors = true; @@ -243,10 +231,9 @@ private void InitializeComponent() this.toggleSiteInfoRemember.AutoSize = true; this.toggleSiteInfoRemember.Checked = true; this.toggleSiteInfoRemember.CheckState = System.Windows.Forms.CheckState.Checked; - this.toggleSiteInfoRemember.Location = new System.Drawing.Point(8, 869); - this.toggleSiteInfoRemember.Margin = new System.Windows.Forms.Padding(6); + this.toggleSiteInfoRemember.Location = new System.Drawing.Point(4, 452); this.toggleSiteInfoRemember.Name = "toggleSiteInfoRemember"; - this.toggleSiteInfoRemember.Size = new System.Drawing.Size(80, 29); + this.toggleSiteInfoRemember.Size = new System.Drawing.Size(80, 17); this.toggleSiteInfoRemember.TabIndex = 12; this.toggleSiteInfoRemember.Text = "On"; this.toggleSiteInfoRemember.Theme = MetroFramework.MetroThemeStyle.Light; @@ -264,48 +251,43 @@ private void InitializeComponent() this.tabInstallPackage.Controls.Add(this.lblLatestReleases); this.tabInstallPackage.Controls.Add(this.lblLocalInstallPackage); this.tabInstallPackage.Controls.Add(this.cboProductName); - this.tabInstallPackage.Controls.Add(this.btnGetLatestRelease); this.tabInstallPackage.Controls.Add(this.btnViewAllReleases); this.tabInstallPackage.HorizontalScrollbarBarColor = true; - this.tabInstallPackage.HorizontalScrollbarSize = 19; - this.tabInstallPackage.Location = new System.Drawing.Point(8, 42); - this.tabInstallPackage.Margin = new System.Windows.Forms.Padding(6); + this.tabInstallPackage.Location = new System.Drawing.Point(4, 35); this.tabInstallPackage.Name = "tabInstallPackage"; - this.tabInstallPackage.Size = new System.Drawing.Size(1198, 515); + this.tabInstallPackage.Size = new System.Drawing.Size(599, 255); this.tabInstallPackage.TabIndex = 0; this.tabInstallPackage.Text = "Install Package Info"; this.tabInstallPackage.VerticalScrollbarBarColor = true; - this.tabInstallPackage.VerticalScrollbarSize = 20; // // cboProductVersion // + this.cboProductVersion.Cursor = System.Windows.Forms.Cursors.Hand; this.cboProductVersion.FormattingEnabled = true; this.cboProductVersion.ItemHeight = 23; - this.cboProductVersion.Location = new System.Drawing.Point(834, 63); - this.cboProductVersion.Margin = new System.Windows.Forms.Padding(6); + this.cboProductVersion.Location = new System.Drawing.Point(476, 33); this.cboProductVersion.Name = "cboProductVersion"; - this.cboProductVersion.Size = new System.Drawing.Size(242, 29); + this.cboProductVersion.Size = new System.Drawing.Size(123, 29); this.cboProductVersion.TabIndex = 30; this.cboProductVersion.SelectedIndexChanged += new System.EventHandler(this.cboProductVersion_SelectedIndexChanged); // // progressBarDownload // this.progressBarDownload.HideProgressText = false; - this.progressBarDownload.Location = new System.Drawing.Point(2, 127); - this.progressBarDownload.Margin = new System.Windows.Forms.Padding(6); + this.progressBarDownload.Location = new System.Drawing.Point(1, 66); this.progressBarDownload.Name = "progressBarDownload"; - this.progressBarDownload.Size = new System.Drawing.Size(1078, 44); + this.progressBarDownload.Size = new System.Drawing.Size(598, 23); this.progressBarDownload.Style = MetroFramework.MetroColorStyle.Blue; this.progressBarDownload.TabIndex = 29; this.progressBarDownload.Visible = false; // // btnInstallPackageNext // + this.btnInstallPackageNext.Cursor = System.Windows.Forms.Cursors.Hand; this.btnInstallPackageNext.Highlight = true; - this.btnInstallPackageNext.Location = new System.Drawing.Point(1014, 415); - this.btnInstallPackageNext.Margin = new System.Windows.Forms.Padding(6); + this.btnInstallPackageNext.Location = new System.Drawing.Point(507, 216); this.btnInstallPackageNext.Name = "btnInstallPackageNext"; - this.btnInstallPackageNext.Size = new System.Drawing.Size(180, 69); + this.btnInstallPackageNext.Size = new System.Drawing.Size(90, 36); this.btnInstallPackageNext.TabIndex = 28; this.btnInstallPackageNext.Text = "&Next"; this.btnInstallPackageNext.Click += new System.EventHandler(this.btnInstallPackageNext_Click); @@ -313,30 +295,29 @@ private void InitializeComponent() // btnLocalInstallPackage // this.btnLocalInstallPackage.Highlight = true; - this.btnLocalInstallPackage.Location = new System.Drawing.Point(1118, 325); - this.btnLocalInstallPackage.Margin = new System.Windows.Forms.Padding(6); + this.btnLocalInstallPackage.Location = new System.Drawing.Point(559, 169); this.btnLocalInstallPackage.Name = "btnLocalInstallPackage"; - this.btnLocalInstallPackage.Size = new System.Drawing.Size(76, 44); + this.btnLocalInstallPackage.Size = new System.Drawing.Size(38, 23); this.btnLocalInstallPackage.TabIndex = 27; this.btnLocalInstallPackage.Text = "..."; + this.btnLocalInstallPackage.Visible = false; this.btnLocalInstallPackage.Click += new System.EventHandler(this.btnLocalInstallPackage_Click); // // txtLocalInstallPackage // this.txtLocalInstallPackage.FontWeight = MetroFramework.MetroTextBoxWeight.Light; - this.txtLocalInstallPackage.Location = new System.Drawing.Point(2, 325); - this.txtLocalInstallPackage.Margin = new System.Windows.Forms.Padding(6); + this.txtLocalInstallPackage.Location = new System.Drawing.Point(1, 169); this.txtLocalInstallPackage.Name = "txtLocalInstallPackage"; this.txtLocalInstallPackage.ReadOnly = true; - this.txtLocalInstallPackage.Size = new System.Drawing.Size(1078, 44); + this.txtLocalInstallPackage.Size = new System.Drawing.Size(539, 23); this.txtLocalInstallPackage.TabIndex = 26; + this.txtLocalInstallPackage.Visible = false; this.txtLocalInstallPackage.Click += new System.EventHandler(this.txtLocalInstallPackage_Click); // // lblLatestReleases // this.lblLatestReleases.AutoSize = true; - this.lblLatestReleases.Location = new System.Drawing.Point(0, 21); - this.lblLatestReleases.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblLatestReleases.Location = new System.Drawing.Point(0, 11); this.lblLatestReleases.Name = "lblLatestReleases"; this.lblLatestReleases.Size = new System.Drawing.Size(161, 19); this.lblLatestReleases.TabIndex = 20; @@ -345,41 +326,29 @@ private void InitializeComponent() // lblLocalInstallPackage // this.lblLocalInstallPackage.AutoSize = true; - this.lblLocalInstallPackage.Location = new System.Drawing.Point(0, 277); - this.lblLocalInstallPackage.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblLocalInstallPackage.Location = new System.Drawing.Point(0, 144); this.lblLocalInstallPackage.Name = "lblLocalInstallPackage"; this.lblLocalInstallPackage.Size = new System.Drawing.Size(127, 19); this.lblLocalInstallPackage.TabIndex = 25; this.lblLocalInstallPackage.Text = "Local Install Package"; + this.lblLocalInstallPackage.Visible = false; // // cboProductName // + this.cboProductName.Cursor = System.Windows.Forms.Cursors.Hand; this.cboProductName.FormattingEnabled = true; this.cboProductName.ItemHeight = 23; - this.cboProductName.Location = new System.Drawing.Point(2, 63); - this.cboProductName.Margin = new System.Windows.Forms.Padding(6); + this.cboProductName.Location = new System.Drawing.Point(1, 33); this.cboProductName.Name = "cboProductName"; - this.cboProductName.Size = new System.Drawing.Size(816, 29); + this.cboProductName.Size = new System.Drawing.Size(459, 29); this.cboProductName.TabIndex = 31; this.cboProductName.SelectedIndexChanged += new System.EventHandler(this.cboProductName_SelectedIndexChanged); // - // btnGetLatestRelease - // - this.btnGetLatestRelease.Location = new System.Drawing.Point(1118, 63); - this.btnGetLatestRelease.Margin = new System.Windows.Forms.Padding(6); - this.btnGetLatestRelease.Name = "btnGetLatestRelease"; - this.btnGetLatestRelease.Size = new System.Drawing.Size(76, 56); - this.btnGetLatestRelease.TabIndex = 22; - this.btnGetLatestRelease.Text = ">"; - this.btnGetLatestRelease.Visible = false; - this.btnGetLatestRelease.Click += new System.EventHandler(this.btnGetLatestRelease_Click); - // // btnViewAllReleases // - this.btnViewAllReleases.Location = new System.Drawing.Point(0, 183); - this.btnViewAllReleases.Margin = new System.Windows.Forms.Padding(6); + this.btnViewAllReleases.Location = new System.Drawing.Point(0, 95); this.btnViewAllReleases.Name = "btnViewAllReleases"; - this.btnViewAllReleases.Size = new System.Drawing.Size(1080, 71); + this.btnViewAllReleases.Size = new System.Drawing.Size(599, 37); this.btnViewAllReleases.Style = MetroFramework.MetroColorStyle.Blue; this.btnViewAllReleases.TabIndex = 23; this.btnViewAllReleases.Text = "View ALL Releases"; @@ -392,12 +361,11 @@ private void InitializeComponent() this.tabControl.Controls.Add(this.tabSiteInfo); this.tabControl.Controls.Add(this.tabDatabaseInfo); this.tabControl.Controls.Add(this.tabProgress); - this.tabControl.Location = new System.Drawing.Point(6, 27); - this.tabControl.Margin = new System.Windows.Forms.Padding(6); + this.tabControl.Location = new System.Drawing.Point(3, 14); this.tabControl.Multiline = true; this.tabControl.Name = "tabControl"; this.tabControl.SelectedIndex = 0; - this.tabControl.Size = new System.Drawing.Size(1214, 565); + this.tabControl.Size = new System.Drawing.Size(607, 294); this.tabControl.TabIndex = 26; // // tabDatabaseInfo @@ -415,33 +383,30 @@ private void InitializeComponent() this.tabDatabaseInfo.Controls.Add(this.lblDBServerName); this.tabDatabaseInfo.Controls.Add(this.txtDBServerName); this.tabDatabaseInfo.HorizontalScrollbarBarColor = true; - this.tabDatabaseInfo.HorizontalScrollbarSize = 19; - this.tabDatabaseInfo.Location = new System.Drawing.Point(8, 42); - this.tabDatabaseInfo.Margin = new System.Windows.Forms.Padding(6); + this.tabDatabaseInfo.Location = new System.Drawing.Point(4, 35); this.tabDatabaseInfo.Name = "tabDatabaseInfo"; - this.tabDatabaseInfo.Size = new System.Drawing.Size(1198, 515); + this.tabDatabaseInfo.Size = new System.Drawing.Size(599, 255); this.tabDatabaseInfo.TabIndex = 3; this.tabDatabaseInfo.Text = "Database Info"; this.tabDatabaseInfo.VerticalScrollbarBarColor = true; - this.tabDatabaseInfo.VerticalScrollbarSize = 20; // // btnDatabaseInfoBack // - this.btnDatabaseInfoBack.Location = new System.Drawing.Point(0, 415); - this.btnDatabaseInfoBack.Margin = new System.Windows.Forms.Padding(6); + this.btnDatabaseInfoBack.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnDatabaseInfoBack.Location = new System.Drawing.Point(0, 216); this.btnDatabaseInfoBack.Name = "btnDatabaseInfoBack"; - this.btnDatabaseInfoBack.Size = new System.Drawing.Size(180, 69); + this.btnDatabaseInfoBack.Size = new System.Drawing.Size(90, 36); this.btnDatabaseInfoBack.TabIndex = 13; this.btnDatabaseInfoBack.Text = "&Back"; this.btnDatabaseInfoBack.Click += new System.EventHandler(this.btnDatabaseInfoBack_Click); // // btnDatabaseInfoNext // + this.btnDatabaseInfoNext.Cursor = System.Windows.Forms.Cursors.Hand; this.btnDatabaseInfoNext.Highlight = true; - this.btnDatabaseInfoNext.Location = new System.Drawing.Point(1014, 415); - this.btnDatabaseInfoNext.Margin = new System.Windows.Forms.Padding(6); + this.btnDatabaseInfoNext.Location = new System.Drawing.Point(507, 216); this.btnDatabaseInfoNext.Name = "btnDatabaseInfoNext"; - this.btnDatabaseInfoNext.Size = new System.Drawing.Size(180, 69); + this.btnDatabaseInfoNext.Size = new System.Drawing.Size(90, 36); this.btnDatabaseInfoNext.TabIndex = 12; this.btnDatabaseInfoNext.Text = "&Next"; this.btnDatabaseInfoNext.Click += new System.EventHandler(this.btnDatabaseInfoNext_Click); @@ -449,8 +414,7 @@ private void InitializeComponent() // lblDBName // this.lblDBName.AutoSize = true; - this.lblDBName.Location = new System.Drawing.Point(0, 212); - this.lblDBName.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblDBName.Location = new System.Drawing.Point(0, 110); this.lblDBName.Name = "lblDBName"; this.lblDBName.Size = new System.Drawing.Size(103, 19); this.lblDBName.TabIndex = 11; @@ -458,10 +422,9 @@ private void InitializeComponent() // // txtDBName // - this.txtDBName.Location = new System.Drawing.Point(0, 258); - this.txtDBName.Margin = new System.Windows.Forms.Padding(6); + this.txtDBName.Location = new System.Drawing.Point(0, 134); this.txtDBName.Name = "txtDBName"; - this.txtDBName.Size = new System.Drawing.Size(540, 44); + this.txtDBName.Size = new System.Drawing.Size(270, 23); this.txtDBName.TabIndex = 3; this.txtDBName.Text = "MySite"; this.txtDBName.UseStyleColors = true; @@ -469,10 +432,9 @@ private void InitializeComponent() // txtDBPassword // this.txtDBPassword.Enabled = false; - this.txtDBPassword.Location = new System.Drawing.Point(680, 258); - this.txtDBPassword.Margin = new System.Windows.Forms.Padding(6); + this.txtDBPassword.Location = new System.Drawing.Point(340, 134); this.txtDBPassword.Name = "txtDBPassword"; - this.txtDBPassword.Size = new System.Drawing.Size(514, 44); + this.txtDBPassword.Size = new System.Drawing.Size(257, 23); this.txtDBPassword.TabIndex = 9; // // lblDBPassword @@ -480,8 +442,7 @@ private void InitializeComponent() this.lblDBPassword.AutoSize = true; this.lblDBPassword.Enabled = false; this.lblDBPassword.FontSize = MetroFramework.MetroLabelSize.Small; - this.lblDBPassword.Location = new System.Drawing.Point(680, 213); - this.lblDBPassword.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblDBPassword.Location = new System.Drawing.Point(340, 111); this.lblDBPassword.Name = "lblDBPassword"; this.lblDBPassword.Size = new System.Drawing.Size(55, 15); this.lblDBPassword.TabIndex = 8; @@ -492,8 +453,7 @@ private void InitializeComponent() this.lblDBUserName.AutoSize = true; this.lblDBUserName.Enabled = false; this.lblDBUserName.FontSize = MetroFramework.MetroLabelSize.Small; - this.lblDBUserName.Location = new System.Drawing.Point(680, 121); - this.lblDBUserName.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblDBUserName.Location = new System.Drawing.Point(340, 63); this.lblDBUserName.Name = "lblDBUserName"; this.lblDBUserName.Size = new System.Drawing.Size(64, 15); this.lblDBUserName.TabIndex = 7; @@ -502,17 +462,15 @@ private void InitializeComponent() // txtDBUserName // this.txtDBUserName.Enabled = false; - this.txtDBUserName.Location = new System.Drawing.Point(680, 163); - this.txtDBUserName.Margin = new System.Windows.Forms.Padding(6); + this.txtDBUserName.Location = new System.Drawing.Point(340, 85); this.txtDBUserName.Name = "txtDBUserName"; - this.txtDBUserName.Size = new System.Drawing.Size(514, 44); + this.txtDBUserName.Size = new System.Drawing.Size(257, 23); this.txtDBUserName.TabIndex = 6; // // rdoSQLServerAuthentication // this.rdoSQLServerAuthentication.AutoSize = true; - this.rdoSQLServerAuthentication.Location = new System.Drawing.Point(642, 87); - this.rdoSQLServerAuthentication.Margin = new System.Windows.Forms.Padding(6); + this.rdoSQLServerAuthentication.Location = new System.Drawing.Point(321, 45); this.rdoSQLServerAuthentication.Name = "rdoSQLServerAuthentication"; this.rdoSQLServerAuthentication.Size = new System.Drawing.Size(161, 15); this.rdoSQLServerAuthentication.TabIndex = 5; @@ -524,8 +482,7 @@ private void InitializeComponent() // this.rdoWindowsAuthentication.AutoSize = true; this.rdoWindowsAuthentication.Checked = true; - this.rdoWindowsAuthentication.Location = new System.Drawing.Point(642, 44); - this.rdoWindowsAuthentication.Margin = new System.Windows.Forms.Padding(6); + this.rdoWindowsAuthentication.Location = new System.Drawing.Point(321, 23); this.rdoWindowsAuthentication.Name = "rdoWindowsAuthentication"; this.rdoWindowsAuthentication.Size = new System.Drawing.Size(154, 15); this.rdoWindowsAuthentication.TabIndex = 4; @@ -537,8 +494,7 @@ private void InitializeComponent() // lblDBServerName // this.lblDBServerName.AutoSize = true; - this.lblDBServerName.Location = new System.Drawing.Point(0, 23); - this.lblDBServerName.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblDBServerName.Location = new System.Drawing.Point(0, 12); this.lblDBServerName.Name = "lblDBServerName"; this.lblDBServerName.Size = new System.Drawing.Size(145, 19); this.lblDBServerName.TabIndex = 3; @@ -546,10 +502,9 @@ private void InitializeComponent() // // txtDBServerName // - this.txtDBServerName.Location = new System.Drawing.Point(0, 71); - this.txtDBServerName.Margin = new System.Windows.Forms.Padding(6); + this.txtDBServerName.Location = new System.Drawing.Point(0, 37); this.txtDBServerName.Name = "txtDBServerName"; - this.txtDBServerName.Size = new System.Drawing.Size(540, 44); + this.txtDBServerName.Size = new System.Drawing.Size(270, 23); this.txtDBServerName.TabIndex = 2; this.txtDBServerName.Text = "(local)"; this.txtDBServerName.UseStyleColors = true; @@ -561,24 +516,21 @@ private void InitializeComponent() this.tabProgress.Controls.Add(this.lblProgress); this.tabProgress.Controls.Add(this.progressBar); this.tabProgress.HorizontalScrollbarBarColor = true; - this.tabProgress.HorizontalScrollbarSize = 19; this.tabProgress.ImeMode = System.Windows.Forms.ImeMode.Disable; - this.tabProgress.Location = new System.Drawing.Point(8, 42); - this.tabProgress.Margin = new System.Windows.Forms.Padding(6); + this.tabProgress.Location = new System.Drawing.Point(4, 35); this.tabProgress.Name = "tabProgress"; - this.tabProgress.Size = new System.Drawing.Size(1198, 515); + this.tabProgress.Size = new System.Drawing.Size(599, 255); this.tabProgress.TabIndex = 2; this.tabProgress.Text = "Progress"; this.tabProgress.VerticalScrollbarBarColor = true; - this.tabProgress.VerticalScrollbarSize = 20; // // btnVisitSite // + this.btnVisitSite.Cursor = System.Windows.Forms.Cursors.Hand; this.btnVisitSite.Highlight = true; - this.btnVisitSite.Location = new System.Drawing.Point(6, 369); - this.btnVisitSite.Margin = new System.Windows.Forms.Padding(6); + this.btnVisitSite.Location = new System.Drawing.Point(3, 192); this.btnVisitSite.Name = "btnVisitSite"; - this.btnVisitSite.Size = new System.Drawing.Size(1186, 115); + this.btnVisitSite.Size = new System.Drawing.Size(593, 60); this.btnVisitSite.Style = MetroFramework.MetroColorStyle.Purple; this.btnVisitSite.TabIndex = 5; this.btnVisitSite.Text = "&Visit Site"; @@ -588,18 +540,16 @@ private void InitializeComponent() // lblProgressStatus // this.lblProgressStatus.FontWeight = MetroFramework.MetroLabelWeight.Regular; - this.lblProgressStatus.Location = new System.Drawing.Point(0, 119); - this.lblProgressStatus.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblProgressStatus.Location = new System.Drawing.Point(0, 62); this.lblProgressStatus.Name = "lblProgressStatus"; - this.lblProgressStatus.Size = new System.Drawing.Size(1194, 37); + this.lblProgressStatus.Size = new System.Drawing.Size(597, 19); this.lblProgressStatus.TabIndex = 4; this.lblProgressStatus.UseStyleColors = true; // // lblProgress // this.lblProgress.AutoSize = true; - this.lblProgress.Location = new System.Drawing.Point(0, 21); - this.lblProgress.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblProgress.Location = new System.Drawing.Point(0, 11); this.lblProgress.Name = "lblProgress"; this.lblProgress.Size = new System.Drawing.Size(60, 19); this.lblProgress.TabIndex = 3; @@ -609,20 +559,18 @@ private void InitializeComponent() // progressBar // this.progressBar.HideProgressText = false; - this.progressBar.Location = new System.Drawing.Point(0, 69); - this.progressBar.Margin = new System.Windows.Forms.Padding(6); + this.progressBar.Location = new System.Drawing.Point(0, 36); this.progressBar.Name = "progressBar"; - this.progressBar.Size = new System.Drawing.Size(1194, 44); + this.progressBar.Size = new System.Drawing.Size(597, 23); this.progressBar.TabIndex = 2; this.progressBar.Visible = false; // // tileDNNAwareness // this.tileDNNAwareness.Cursor = System.Windows.Forms.Cursors.Hand; - this.tileDNNAwareness.Location = new System.Drawing.Point(946, 646); - this.tileDNNAwareness.Margin = new System.Windows.Forms.Padding(6); + this.tileDNNAwareness.Location = new System.Drawing.Point(473, 336); this.tileDNNAwareness.Name = "tileDNNAwareness"; - this.tileDNNAwareness.Size = new System.Drawing.Size(262, 96); + this.tileDNNAwareness.Size = new System.Drawing.Size(131, 50); this.tileDNNAwareness.Style = MetroFramework.MetroColorStyle.Blue; this.tileDNNAwareness.TabIndex = 28; this.tileDNNAwareness.Text = "@DNNAwareness"; @@ -632,10 +580,9 @@ private void InitializeComponent() // tileDNNDocs // this.tileDNNDocs.Cursor = System.Windows.Forms.Cursors.Hand; - this.tileDNNDocs.Location = new System.Drawing.Point(352, 748); - this.tileDNNDocs.Margin = new System.Windows.Forms.Padding(6); + this.tileDNNDocs.Location = new System.Drawing.Point(176, 389); this.tileDNNDocs.Name = "tileDNNDocs"; - this.tileDNNDocs.Size = new System.Drawing.Size(288, 96); + this.tileDNNDocs.Size = new System.Drawing.Size(144, 50); this.tileDNNDocs.Style = MetroFramework.MetroColorStyle.Lime; this.tileDNNDocs.TabIndex = 29; this.tileDNNDocs.Text = "DNN Docs"; @@ -647,10 +594,9 @@ private void InitializeComponent() // this.tileMorenvQuickProducts.BackColor = System.Drawing.SystemColors.Control; this.tileMorenvQuickProducts.Cursor = System.Windows.Forms.Cursors.Hand; - this.tileMorenvQuickProducts.Location = new System.Drawing.Point(352, 644); - this.tileMorenvQuickProducts.Margin = new System.Windows.Forms.Padding(6); + this.tileMorenvQuickProducts.Location = new System.Drawing.Point(176, 335); this.tileMorenvQuickProducts.Name = "tileMorenvQuickProducts"; - this.tileMorenvQuickProducts.Size = new System.Drawing.Size(582, 96); + this.tileMorenvQuickProducts.Size = new System.Drawing.Size(291, 50); this.tileMorenvQuickProducts.Style = MetroFramework.MetroColorStyle.Yellow; this.tileMorenvQuickProducts.TabIndex = 30; this.tileMorenvQuickProducts.Text = "nvQuickSite Wiki"; @@ -661,8 +607,7 @@ private void InitializeComponent() // lblRemember // this.lblRemember.AutoSize = true; - this.lblRemember.Location = new System.Drawing.Point(180, 865); - this.lblRemember.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + this.lblRemember.Location = new System.Drawing.Point(90, 450); this.lblRemember.Name = "lblRemember"; this.lblRemember.Size = new System.Drawing.Size(146, 19); this.lblRemember.TabIndex = 13; @@ -670,13 +615,37 @@ private void InitializeComponent() this.lblRemember.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.lblRemember.Visible = false; // + // tileDNNCommunity + // + this.tileDNNCommunity.Cursor = System.Windows.Forms.Cursors.Hand; + this.tileDNNCommunity.Location = new System.Drawing.Point(326, 389); + this.tileDNNCommunity.Name = "tileDNNCommunity"; + this.tileDNNCommunity.Size = new System.Drawing.Size(278, 50); + this.tileDNNCommunity.Style = MetroFramework.MetroColorStyle.Purple; + this.tileDNNCommunity.TabIndex = 31; + this.tileDNNCommunity.Text = "DNN Community"; + this.tileDNNCommunity.TextAlign = System.Drawing.ContentAlignment.BottomRight; + this.tileDNNCommunity.TileTextFontWeight = MetroFramework.MetroTileTextWeight.Bold; + this.tileDNNCommunity.Click += new System.EventHandler(this.tileDNNCommunity_Click); + // + // btnViewExistingSites + // + this.btnViewExistingSites.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnViewExistingSites.Highlight = true; + this.btnViewExistingSites.Location = new System.Drawing.Point(7, 312); + this.btnViewExistingSites.Name = "btnViewExistingSites"; + this.btnViewExistingSites.Size = new System.Drawing.Size(162, 23); + this.btnViewExistingSites.Style = MetroFramework.MetroColorStyle.Orange; + this.btnViewExistingSites.TabIndex = 32; + this.btnViewExistingSites.Text = "View Existing Sites"; + this.btnViewExistingSites.Click += new System.EventHandler(this.btnViewExistingSites_Click); + // // tileQuickSettings // this.tileQuickSettings.Cursor = System.Windows.Forms.Cursors.Hand; - this.tileQuickSettings.Location = new System.Drawing.Point(14, 644); - this.tileQuickSettings.Margin = new System.Windows.Forms.Padding(6); + this.tileQuickSettings.Location = new System.Drawing.Point(7, 335); this.tileQuickSettings.Name = "tileQuickSettings"; - this.tileQuickSettings.Size = new System.Drawing.Size(324, 200); + this.tileQuickSettings.Size = new System.Drawing.Size(162, 104); this.tileQuickSettings.Style = MetroFramework.MetroColorStyle.Orange; this.tileQuickSettings.TabIndex = 27; this.tileQuickSettings.Text = "nvQuickSite Settings"; @@ -687,24 +656,11 @@ private void InitializeComponent() this.tileQuickSettings.UseTileImage = true; this.tileQuickSettings.Click += new System.EventHandler(this.tileQuickSettings_Click); // - // tileDNNCommunity - // - this.tileDNNCommunity.Cursor = System.Windows.Forms.Cursors.Hand; - this.tileDNNCommunity.Location = new System.Drawing.Point(652, 748); - this.tileDNNCommunity.Margin = new System.Windows.Forms.Padding(6); - this.tileDNNCommunity.Name = "tileDNNCommunity"; - this.tileDNNCommunity.Size = new System.Drawing.Size(556, 96); - this.tileDNNCommunity.Style = MetroFramework.MetroColorStyle.Purple; - this.tileDNNCommunity.TabIndex = 31; - this.tileDNNCommunity.Text = "DNN Community"; - this.tileDNNCommunity.TextAlign = System.Drawing.ContentAlignment.BottomRight; - this.tileDNNCommunity.TileTextFontWeight = MetroFramework.MetroTileTextWeight.Bold; - this.tileDNNCommunity.Click += new System.EventHandler(this.tileDNNCommunity_Click); - // // Start // - this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.btnViewExistingSites); this.Controls.Add(this.tileDNNCommunity); this.Controls.Add(this.lblRemember); this.Controls.Add(this.tileMorenvQuickProducts); @@ -713,9 +669,8 @@ private void InitializeComponent() this.Controls.Add(this.toggleSiteInfoRemember); this.Controls.Add(this.tileQuickSettings); this.Controls.Add(this.tabControl); - this.Margin = new System.Windows.Forms.Padding(6); this.Name = "Start"; - this.Size = new System.Drawing.Size(1220, 904); + this.Size = new System.Drawing.Size(610, 470); this.tabSiteInfo.ResumeLayout(false); this.tabSiteInfo.PerformLayout(); this.tabInstallPackage.ResumeLayout(false); @@ -739,7 +694,6 @@ private void InitializeComponent() private MetroFramework.Controls.MetroButton btnViewAllReleases; //private MetroFramework.Controls.MetroComboBox cboLatestReleases; private MetroFramework.Controls.MetroComboBox cboProductName; - private MetroFramework.Controls.MetroButton btnGetLatestRelease; private MetroFramework.Controls.MetroTabControl tabControl; private MetroFramework.Controls.MetroTile tileQuickSettings; private MetroFramework.Controls.MetroTile tileDNNAwareness; @@ -782,5 +736,6 @@ private void InitializeComponent() private MetroFramework.Controls.MetroTextBox txtInstallSubFolder; private MetroFramework.Controls.MetroComboBox cboProductVersion; private MetroFramework.Controls.MetroTile tileDNNCommunity; + private MetroFramework.Controls.MetroButton btnViewExistingSites; } } diff --git a/nvQuickSite/Start.cs b/nvQuickSite/Start.cs index 0c72f4aa..cc3fe0b7 100644 --- a/nvQuickSite/Start.cs +++ b/nvQuickSite/Start.cs @@ -1,248 +1,313 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using System; -using System.ComponentModel; -using System.Drawing; -using System.Data; -using System.Data.SqlClient; -using System.Linq; -using System.Net; -using System.Xml.Linq; -using System.Windows.Forms; -using System.IO; -using System.Security.AccessControl; -using System.Net.Sockets; -using System.Diagnostics; -using MetroFramework.Controls; -using Microsoft.Web.Administration; -using Ionic.Zip; -using Ookii.Dialogs; -using nvQuickSite.Controllers; -using nvQuickSite.Models; -using System.Collections.Generic; +// Copyright (c) 2016-2020 nvisionative, Inc. +// +// This file is part of nvQuickSite. +// +// nvQuickSite is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// nvQuickSite is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with nvQuickSite. If not, see . namespace nvQuickSite { + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Data; + using System.Diagnostics; + using System.Drawing; + using System.IO; + using System.Linq; + using System.Net; + using System.Windows.Forms; + + using Ionic.Zip; + using MetroFramework.Controls; + using nvQuickSite.Controllers; + using nvQuickSite.Controllers.Exceptions; + using nvQuickSite.Controls.Settings; + using nvQuickSite.Controls.Sites; + using nvQuickSite.Exceptions; + using nvQuickSite.Models; + using Ookii.Dialogs; + using Serilog; + using Serilog.Core; + + /// + /// Implementes the UI tabs and tiles logic. + /// public partial class Start : MetroUserControl { + private readonly LoggingLevelSwitch loggingLevelSwitch; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "No performance concerns")] + private readonly Timer downloadProgressLogTimer; + private long totalSize; + private long total; + private long lastVal; + private long sum; + + /// + /// Initializes a new instance of the class. + /// + /// An object that can be used to dynamically change the logging level at runtime. + public Start(Serilog.Core.LoggingLevelSwitch loggingLevelSwitch) + { + this.InitializeComponent(); + this.InitializeTabs(); + this.LoadPackages(); + this.ReadUserSettings(); + this.loggingLevelSwitch = loggingLevelSwitch; + this.downloadProgressLogTimer = new Timer() { Interval = 2000 }; + this.downloadProgressLogTimer.Tick += this.DownloadProgressLogTimer_Tick; + } private IEnumerable Packages { get; set; } - protected string currentVersion; - protected string currentUrl; - - public Start() - { - InitializeComponent(); - - InitializeTabs(); + private string InstallFolder => Path.Combine(this.txtInstallBaseFolder.Text, this.txtInstallSubFolder.Text); - LoadPackages(); - RememberFieldValues(); - } + private string SiteName => this.txtSiteNamePrefix.Text + this.txtSiteNameSuffix.Text; private void LoadPackages() { try { - cboProductName.Items.Clear(); - cboProductVersion.Items.Clear(); + this.cboProductName.Items.Clear(); + this.cboProductVersion.Items.Clear(); - Packages = PackageController.GetPackageList(); - foreach (var did in Packages.OrderByDescending(p => p.version).Select(p => p.did).Distinct()) + this.Packages = PackageController.GetPackageList(); + foreach (var did in this.Packages.OrderByDescending(p => p.version).Select(p => p.did).Distinct()) { if (did == "dnn-platform-rc") { if (Properties.Settings.Default.ShowReleaseCandidates) { - cboProductName.Items.Add(new ComboItem(Packages.First(p => p.did == did).name, did)); + this.cboProductName.Items.Add(new ComboItem(this.Packages.First(p => p.did == did).name, did)); } - } else + } + else { - cboProductName.Items.Add(new ComboItem(Packages.First(p => p.did == did).name, did)); + this.cboProductName.Items.Add(new ComboItem(this.Packages.First(p => p.did == did).name, did)); } } - if (cboProductName.Items.Count > 0) + + if (this.cboProductName.Items.Count > 0) { - cboProductName.SelectedIndex = 0; - LoadPackageVersions(((ComboItem)cboProductName.SelectedItem).Value); + this.cboProductName.SelectedIndex = 0; + this.LoadPackageVersions(((ComboItem)this.cboProductName.SelectedItem).Value); } } - catch (Exception ex) + catch (WebException) { - lblLatestReleases.Text = "Error: " + ex.Message + " --- you may be able to use a Local Install Package"; // "INTERNET CURRENTLY UNAVAILABLE: Use Local Install Package Instead"; - lblLatestReleases.CustomForeColor = true; - lblLatestReleases.ForeColor = Color.DarkRed; - cboProductName.Enabled = false; - cboProductVersion.Enabled = false; - btnGetLatestRelease.Enabled = false; + this.lblLatestReleases.Text = "It appears you have no internet, but you can still use Local Install Packages."; + this.lblLatestReleases.CustomForeColor = true; + this.lblLatestReleases.ForeColor = Color.DarkRed; + this.cboProductName.Enabled = false; + this.cboProductVersion.Enabled = false; } } - private void RememberFieldValues() + private void ReadUserSettings() { + Log.Logger.Information("Reading current user settings"); + Log.Logger.Debug("Current user settings: {@userSettings}", Properties.Settings.Default); if (Properties.Settings.Default.RememberFieldValues) { - txtSiteNamePrefix.Text = Properties.Settings.Default.SiteNamePrefixRecent; - txtSiteNameSuffix.Text = Properties.Settings.Default.SiteNameSuffixRecent; - chkSiteSpecificAppPool.Checked = Properties.Settings.Default.AppPoolRecent; - chkDeleteSiteIfExists.Checked = Properties.Settings.Default.DeleteSiteInIISRecent; - txtInstallBaseFolder.Text = Properties.Settings.Default.InstallBaseFolderRecent; - - txtDBServerName.Text = Properties.Settings.Default.DatabaseServerNameRecent; - txtDBName.Text = Properties.Settings.Default.DatabaseNameRecent; + var enableLocalInstallPackage = Properties.Settings.Default.EnableLocalPackageInstall; + this.lblLocalInstallPackage.Visible = enableLocalInstallPackage; + this.txtLocalInstallPackage.Visible = enableLocalInstallPackage; + this.btnLocalInstallPackage.Visible = enableLocalInstallPackage; + + this.txtSiteNamePrefix.Text = Properties.Settings.Default.SiteNamePrefixRecent; + this.txtSiteNameSuffix.Text = Properties.Settings.Default.SiteNameSuffixRecent; + this.chkSiteSpecificAppPool.Checked = Properties.Settings.Default.AppPoolRecent; + this.chkDeleteSiteIfExists.Checked = Properties.Settings.Default.DeleteSiteInIISRecent; + this.txtInstallBaseFolder.Text = Properties.Settings.Default.InstallBaseFolderRecent; + + this.txtDBServerName.Text = Properties.Settings.Default.DatabaseServerNameRecent; + this.txtDBName.Text = Properties.Settings.Default.DatabaseNameRecent; + this.txtDBUserName.Text = Properties.Settings.Default.DatabaseUserNameRecent; } } - #region "Tabs" + private void SaveUserSettings() + { + if (Properties.Settings.Default.RememberFieldValues) + { + Properties.Settings.Default.SiteNamePrefixRecent = this.txtSiteNamePrefix.Text; + Properties.Settings.Default.SiteNameSuffixRecent = this.txtSiteNameSuffix.Text; + Properties.Settings.Default.AppPoolRecent = this.chkSiteSpecificAppPool.Checked; + Properties.Settings.Default.DeleteSiteInIISRecent = this.chkDeleteSiteIfExists.Checked; + Properties.Settings.Default.InstallBaseFolderRecent = this.txtInstallBaseFolder.Text; + + Properties.Settings.Default.DatabaseServerNameRecent = this.txtDBServerName.Text; + Properties.Settings.Default.DatabaseNameRecent = this.txtDBName.Text; + Properties.Settings.Default.DatabaseUserNameRecent = this.txtDBUserName.Text; + + Properties.Settings.Default.Save(); + Log.Logger.Information("Saved user settings"); + Log.Logger.Debug("Saved user settings: {@userSettings}", Properties.Settings.Default); + return; + } + + Log.Logger.Information("User settings changed"); + Log.Logger.Debug("User settings changed: {@userSettings}", Properties.Settings.Default); + } private void InitializeTabs() { - tabControl.SelectedIndex = 0; - tabSiteInfo.Enabled = false; - tabControl.TabPages.Remove(tabSiteInfo); - tabDatabaseInfo.Enabled = false; - tabControl.TabPages.Remove(tabDatabaseInfo); - tabProgress.Enabled = false; - tabControl.TabPages.Remove(tabProgress); + this.tabControl.SelectedIndex = 0; + this.tabSiteInfo.Enabled = false; + this.tabControl.TabPages.Remove(this.tabSiteInfo); + this.tabDatabaseInfo.Enabled = false; + this.tabControl.TabPages.Remove(this.tabDatabaseInfo); + this.tabProgress.Enabled = false; + this.tabControl.TabPages.Remove(this.tabProgress); } - #region "Install Package" private void LoadPackageVersions(string packageId) { - cboProductVersion.Items.Clear(); - foreach (var package in Packages.Where(p => p.did == packageId).OrderByDescending(p => p.version)) + this.cboProductVersion.Items.Clear(); + foreach (var package in this.Packages.Where(p => p.did == packageId).OrderByDescending(p => p.version)) { - cboProductVersion.Items.Add(new ComboItem(package.version, package.version)); + this.cboProductVersion.Items.Add(new ComboItem(package.version, package.version)); } - if (cboProductVersion.Items.Count > 0) + + if (this.cboProductVersion.Items.Count > 0) { - cboProductVersion.SelectedIndex = 0; + this.cboProductVersion.SelectedIndex = 0; } } private void cboProductName_SelectedIndexChanged(object sender, EventArgs e) { - var did = ((ComboItem)cboProductName.SelectedItem).Value; - LoadPackageVersions(did); - DisplayPackagePath(); + var did = ((ComboItem)this.cboProductName.SelectedItem).Value; + this.LoadPackageVersions(did); + this.DisplayPackagePath(); } private void cboProductVersion_SelectedIndexChanged(object sender, EventArgs e) { - var did = ((ComboItem)cboProductVersion.SelectedItem).Value; - DisplayPackagePath(); + var did = ((ComboItem)this.cboProductVersion.SelectedItem).Value; + this.DisplayPackagePath(); } private void DisplayPackagePath() { - if (cboProductName.SelectedItem == null || cboProductVersion.SelectedItem == null) { return; } - Models.Package package; - var url = ""; - var fileName = ""; + if (this.cboProductName.SelectedItem == null || this.cboProductVersion.SelectedItem == null) + { + return; + } + + Package package; + var fileName = string.Empty; - package = Packages.FirstOrDefault(p => p.did == ((ComboItem)cboProductName.SelectedItem).Value && p.version == ((ComboItem)cboProductVersion.SelectedItem).Value); + package = this.Packages.FirstOrDefault(p => p.did == ((ComboItem)this.cboProductName.SelectedItem).Value && p.version == ((ComboItem)this.cboProductVersion.SelectedItem).Value); fileName = package.url.Split('/').Last(); - var downloadDirectory = GetDownloadDirectory(); + var downloadDirectory = FileSystemController.GetDownloadDirectory(); var packageFullpath = downloadDirectory + fileName; if (File.Exists(packageFullpath)) - txtLocalInstallPackage.Text = packageFullpath; + { + this.txtLocalInstallPackage.Text = packageFullpath; + } else - txtLocalInstallPackage.Text = null; + { + this.txtLocalInstallPackage.Text = null; + } } private void btnGetLatestRelease_Click(object sender, EventArgs e) { - GetOnlineVersion(); - } - - private string GetDownloadDirectory() - { - return Directory.GetCurrentDirectory() + @"\Downloads\"; + this.GetOnlineVersion(); } private void GetOnlineVersion() { - if (cboProductName.SelectedItem == null || cboProductVersion.SelectedItem == null) { return; } - Models.Package package; - package = Packages.FirstOrDefault(p => p.did == ((ComboItem)cboProductName.SelectedItem).Value && p.version == ((ComboItem)cboProductVersion.SelectedItem).Value); + if (this.cboProductName.SelectedItem == null || this.cboProductVersion.SelectedItem == null) + { + return; + } + + Package package; + package = this.Packages.FirstOrDefault(p => p.did == ((ComboItem)this.cboProductName.SelectedItem).Value && p.version == ((ComboItem)this.cboProductVersion.SelectedItem).Value); var url = package.url; var fileName = package.url.Split('/').Last(); - WebClient client = new WebClient(); - client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); - client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); - - var downloadDirectory = GetDownloadDirectory(); - if (!Directory.Exists(downloadDirectory)) + using (WebClient client = new WebClient()) { - Directory.CreateDirectory(downloadDirectory); - } + client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(this.client_DownloadProgressChanged); + client.DownloadFileCompleted += new AsyncCompletedEventHandler(this.client_DownloadFileCompleted); + var downloadDirectory = FileSystemController.GetDownloadDirectory(); + if (!Directory.Exists(downloadDirectory)) + { + Directory.CreateDirectory(downloadDirectory); + } - var dlContinue = true; - if (File.Exists(downloadDirectory + fileName)) - { - DialogResult result = MessageBox.Show("Install Package is already downloaded. Would you like to download it again? This will replace the existing download.", - "Download Install Package", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (result == DialogResult.No) + var dlContinue = true; + if (File.Exists(downloadDirectory + fileName)) { - dlContinue = false; + var result = DialogController.ShowMessage( + "Get Online Version", + "Install Package is already downloaded. Would you like to download\nit again? This will replace the existing download.", + SystemIcons.Warning, + DialogController.DialogButtons.YesNo); + + if (result == DialogResult.No) + { + dlContinue = false; + } } - } - if (dlContinue) - { - client.DownloadFileAsync(new Uri(url), downloadDirectory + fileName); - progressBarDownload.BackColor = Color.WhiteSmoke; - progressBarDownload.Visible = true; - } - else - { - txtLocalInstallPackage.Text = Directory.GetCurrentDirectory() + "\\Downloads\\" + Path.GetFileName(url); - Properties.Settings.Default.LocalInstallPackageRecent = downloadDirectory; - Properties.Settings.Default.Save(); - ValidateInstallPackage(); + if (dlContinue) + { + Log.Logger.Information("Downloading package from {url}", url); + this.downloadProgressLogTimer.Start(); + client.DownloadFileAsync(new Uri(url), downloadDirectory + fileName); + this.progressBarDownload.BackColor = Color.WhiteSmoke; + this.progressBarDownload.Visible = true; + } + else + { + this.txtLocalInstallPackage.Text = Directory.GetCurrentDirectory() + "\\Downloads\\" + Path.GetFileName(url); + Properties.Settings.Default.LocalInstallPackageRecent = downloadDirectory; + Properties.Settings.Default.Save(); + Log.Logger.Information("Using local install package {filePath}", this.txtLocalInstallPackage.Text); + this.ValidateInstallPackage(); + } } } private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { - double bytesIn = double.Parse(e.BytesReceived.ToString()); - double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); + double bytesIn = Convert.ToDouble(e.BytesReceived); + double totalBytes = Convert.ToDouble(e.TotalBytesToReceive); double percentage = bytesIn / totalBytes * 100; - progressBarDownload.Value = int.Parse(Math.Truncate(percentage).ToString()); + this.progressBarDownload.Value = Convert.ToInt32(percentage); } - void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) + private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { - Models.Package package; - var url = ""; - var fileName = ""; + Package package; + var fileName = string.Empty; - package = Packages.FirstOrDefault(p => p.did == ((ComboItem)cboProductName.SelectedItem).Value && p.version == ((ComboItem)cboProductVersion.SelectedItem).Value); + package = this.Packages.FirstOrDefault(p => p.did == ((ComboItem)this.cboProductName.SelectedItem).Value && p.version == ((ComboItem)this.cboProductVersion.SelectedItem).Value); fileName = package.url.Split('/').Last(); + this.downloadProgressLogTimer.Stop(); + Log.Logger.Information("Completed download of {fileName}", fileName); - txtLocalInstallPackage.Text = Directory.GetCurrentDirectory() + @"\Downloads\" + fileName; + this.txtLocalInstallPackage.Text = Directory.GetCurrentDirectory() + @"\Downloads\" + fileName; + Log.Logger.Information("Saved {filePath}", this.txtLocalInstallPackage.Text); Properties.Settings.Default.LocalInstallPackageRecent = Directory.GetCurrentDirectory() + @"\Downloads\"; Properties.Settings.Default.Save(); - ValidateInstallPackage(); + this.ValidateInstallPackage(); } private void btnViewAllReleases_Click(object sender, EventArgs e) @@ -252,856 +317,364 @@ private void btnViewAllReleases_Click(object sender, EventArgs e) private void txtLocalInstallPackage_Click(object sender, EventArgs e) { - openFileDiag(); + this.openFileDiag(); } private void btnLocalInstallPackage_Click(object sender, EventArgs e) { - openFileDiag(); + this.openFileDiag(); } private void openFileDiag() { - OpenFileDialog fileDiag = new OpenFileDialog(); - fileDiag.Filter = "ZIP Files|*.zip"; - fileDiag.InitialDirectory = Properties.Settings.Default.LocalInstallPackageRecent; - DialogResult result = fileDiag.ShowDialog(); - - if (result == DialogResult.OK) + using (OpenFileDialog fileDiag = new OpenFileDialog()) { - txtLocalInstallPackage.Text = fileDiag.FileName; - Properties.Settings.Default.LocalInstallPackageRecent = Path.GetDirectoryName(fileDiag.FileName); - Properties.Settings.Default.Save(); + fileDiag.Filter = "ZIP Files|*.zip"; + fileDiag.InitialDirectory = Properties.Settings.Default.LocalInstallPackageRecent; + DialogResult result = fileDiag.ShowDialog(); + + if (result == DialogResult.OK) + { + this.txtLocalInstallPackage.Text = fileDiag.FileName; + Properties.Settings.Default.LocalInstallPackageRecent = Path.GetDirectoryName(fileDiag.FileName); + Properties.Settings.Default.Save(); + } } } private void btnInstallPackageNext_Click(object sender, EventArgs e) { - if (txtLocalInstallPackage.Text == "") + if ((string.IsNullOrWhiteSpace(this.txtLocalInstallPackage.Text) || !Properties.Settings.Default.EnableLocalPackageInstall) && PackageController.IsOnline) { - GetOnlineVersion(); + this.GetOnlineVersion(); + return; } - else + + var result = DialogController.ShowMessage( + "Confirm: Use Local Package?", + "Click 'Yes' to use the Local Install Package. Click 'No' to attempt\ndownload of the selected Download Install Package.", + SystemIcons.Question, + DialogController.DialogButtons.YesNo); + + if (result == DialogResult.No && PackageController.IsOnline) { - DialogResult result = MessageBox.Show("Click 'Yes' to use the Local Install Package. Click 'No' to attempt download of the selected Download Install Package.", - "Confirm: Use Local Package?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (result == DialogResult.No) - { - GetOnlineVersion(); - } - else - { - progressBarDownload.Visible = false; - ValidateInstallPackage(); - } + this.GetOnlineVersion(); + return; } + + this.progressBarDownload.Visible = false; + this.ValidateInstallPackage(); } private void ValidateInstallPackage() { - //if (Package.Validate(txtLocalInstallPackage.Text)) - //{ - tabInstallPackage.Enabled = false; - tabControl.TabPages.Insert(1, tabSiteInfo); - tabSiteInfo.Enabled = true; - tabDatabaseInfo.Enabled = false; - tabProgress.Enabled = false; - tabControl.SelectedIndex = 1; - //} - //else - //{ - // MessageBox.Show("You must first Download or select a valid Local Install Package.", "Install Package", MessageBoxButtons.OK, MessageBoxIcon.Warning); - //} + this.tabInstallPackage.Enabled = false; + this.tabControl.TabPages.Insert(1, this.tabSiteInfo); + this.tabSiteInfo.Enabled = true; + this.tabDatabaseInfo.Enabled = false; + this.tabProgress.Enabled = false; + this.tabControl.SelectedIndex = 1; } - #endregion - - #region "Site Info" - //private void txtLocation_Click(object sender, EventArgs e) - //{ - // openFolderDiag(); - //} - private void btnLocation_Click(object sender, EventArgs e) { - openFolderDiag(); + this.openFolderDiag(); } private void openFolderDiag() { - VistaFolderBrowserDialog diag = new VistaFolderBrowserDialog(); - diag.RootFolder = Environment.SpecialFolder.MyComputer; - diag.SelectedPath = Properties.Settings.Default.InstallBaseFolderRecent; - DialogResult result = diag.ShowDialog(); - - if (result == DialogResult.OK) + using (VistaFolderBrowserDialog diag = new VistaFolderBrowserDialog()) { - txtInstallBaseFolder.Text = diag.SelectedPath; - Properties.Settings.Default.InstallBaseFolderRecent = diag.SelectedPath; - Properties.Settings.Default.Save(); + diag.RootFolder = Environment.SpecialFolder.MyComputer; + diag.SelectedPath = Properties.Settings.Default.InstallBaseFolderRecent; + DialogResult result = diag.ShowDialog(); + + if (result == DialogResult.OK) + { + this.txtInstallBaseFolder.Text = diag.SelectedPath; + Properties.Settings.Default.InstallBaseFolderRecent = diag.SelectedPath; + Properties.Settings.Default.Save(); + } } } private void btnSiteInfoBack_Click(object sender, EventArgs e) { - tabSiteInfo.Enabled = false; - tabControl.TabPages.Remove(tabSiteInfo); - tabInstallPackage.Enabled = true; - tabControl.SelectedIndex = 0; + this.tabSiteInfo.Enabled = false; + this.tabControl.TabPages.Remove(this.tabSiteInfo); + this.tabInstallPackage.Enabled = true; + this.tabControl.SelectedIndex = 0; } private void txtSiteNamePrefix_TextChanged(object sender, EventArgs e) { - txtInstallSubFolder.Text = txtSiteNamePrefix.Text; - txtDBName.Text = txtSiteNamePrefix.Text; + this.txtInstallSubFolder.Text = this.txtSiteNamePrefix.Text; + this.txtDBName.Text = this.txtSiteNamePrefix.Text; } private void btnSiteInfoNext_Click(object sender, EventArgs e) { - bool proceed = false; + bool proceed; - if (txtInstallBaseFolder.Text != "" && txtInstallSubFolder.Text != "" && txtSiteNamePrefix.Text != "") + if (string.IsNullOrWhiteSpace(this.txtInstallBaseFolder.Text) || string.IsNullOrWhiteSpace(this.txtInstallSubFolder.Text) || string.IsNullOrWhiteSpace(this.txtSiteNamePrefix.Text)) { - string installFolder = txtInstallBaseFolder.Text + "\\" + txtInstallSubFolder.Text; + DialogController.ShowMessage( + "Site Info", + "Please make sure you have entered a Site Name and Install Folder", + SystemIcons.Warning, + DialogController.DialogButtons.OK); - if (!Directory.Exists(installFolder)) - { - var dialogMessage = "The entered location does not exist. Do you wish to create it?"; - var dialogIcon = SystemIcons.Warning.ToBitmap(); - var doNotWarnAgain = Properties.Settings.Default.LocationDoNotWarnAgain; - var msgBoxYesNoIgnore = new MsgBoxYesNoIgnore(doNotWarnAgain, dialogMessage, dialogIcon); - if (!doNotWarnAgain) - { - var result = msgBoxYesNoIgnore.ShowDialog(); - if (result == DialogResult.Yes) - { - Directory.CreateDirectory(installFolder); - proceed = true; - } - else - { - proceed = false; - } - } - else - { - Directory.CreateDirectory(installFolder); - proceed = true; + return; + } - } - Properties.Settings.Default.LocationDoNotWarnAgain = msgBoxYesNoIgnore.DoNotWarnAgain; - Properties.Settings.Default.Save(); - } - else - { - proceed = true; - } + if (!Directory.Exists(this.InstallFolder)) + { + var doNotWarnAgain = Properties.Settings.Default.LocationDoNotWarnAgain; - if (proceed) + if (!doNotWarnAgain) { - if (!DirectoryEmpty(installFolder)) + var result = DialogController.ShowMessage( + "Site Info", + "The entered location does not exist. Do you wish to create it?", + SystemIcons.Warning, + DialogController.DialogButtons.YesNoIgnore, + Properties.Settings.Default.LocationDoNotWarnAgain); + + if (result == DialogResult.Yes) { - var confirmResult = MessageBox.Show("All files and folders at this location will be deleted prior to installation of the new DNN instance. Do you wish to proceed?", - "Confirm Installation", - MessageBoxButtons.YesNo, MessageBoxIcon.Information); - if (confirmResult == DialogResult.No) - { - proceed = false; - } - else - { - proceed = true; - } + Directory.CreateDirectory(this.InstallFolder); + proceed = true; } else { - proceed = true; + proceed = false; } - } - if (proceed) - { - tabInstallPackage.Enabled = false; - tabSiteInfo.Enabled = false; - tabControl.TabPages.Insert(2, tabDatabaseInfo); - tabDatabaseInfo.Enabled = true; - tabProgress.Enabled = false; - tabControl.SelectedIndex = 2; - if (Properties.Settings.Default.RememberFieldValues) - { - Properties.Settings.Default.SiteNamePrefixRecent = txtSiteNamePrefix.Text; - Properties.Settings.Default.SiteNameSuffixRecent = txtSiteNameSuffix.Text; - Properties.Settings.Default.AppPoolRecent = chkSiteSpecificAppPool.Checked; - Properties.Settings.Default.DeleteSiteInIISRecent = chkDeleteSiteIfExists.Checked; - Properties.Settings.Default.Save(); - } + Properties.Settings.Default.LocationDoNotWarnAgain = DialogController.DoNotWarnAgain; + Properties.Settings.Default.Save(); } - } - else - { - MessageBox.Show("Please make sure you have entered a Site Name and Install Folder.", "Site Info", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - } - - private bool DirectoryEmpty(string path) - { - return !Directory.EnumerateFileSystemEntries(path).Any(); - } - - #endregion - - #region "Database Info" - - private void rdoWindowsAuthentication_CheckedChanged(object sender, EventArgs e) - { - lblDBUserName.Enabled = false; - txtDBUserName.Enabled = false; - txtDBUserName.UseStyleColors = true; - lblDBPassword.Enabled = false; - txtDBPassword.Enabled = false; - txtDBPassword.UseStyleColors = true; - } - - private void rdoSQLServerAuthentication_CheckedChanged(object sender, EventArgs e) - { - lblDBUserName.Enabled = true; - txtDBUserName.Enabled = true; - txtDBUserName.UseStyleColors = false; - lblDBPassword.Enabled = true; - txtDBPassword.Enabled = true; - txtDBPassword.UseStyleColors = false; - } - - private void btnDatabaseInfoBack_Click(object sender, EventArgs e) - { - tabInstallPackage.Enabled = false; - tabSiteInfo.Enabled = true; - tabDatabaseInfo.Enabled = false; - tabControl.TabPages.Remove(tabDatabaseInfo); - tabControl.SelectedIndex = 1; - } - - private void btnDatabaseInfoNext_Click(object sender, EventArgs e) - { - if (txtDBServerName.Text != "" && txtDBName.Text != "") - { - if (CreateSiteInIIS()) + else { - if (UpdateHostsFile()) - { - if (CreateDirectories()) - { - if (CreateDatabase()) - { - if (SetDatabasePermissions()) - { - tabInstallPackage.Enabled = false; - tabSiteInfo.Enabled = false; - tabDatabaseInfo.Enabled = false; - tabControl.TabPages.Insert(3, tabProgress); - tabProgress.Enabled = true; - lblProgress.Visible = true; - progressBar.Visible = true; - tabControl.SelectedIndex = 3; - - if (Properties.Settings.Default.RememberFieldValues) - { - Properties.Settings.Default.DatabaseServerNameRecent = txtDBServerName.Text; - Properties.Settings.Default.DatabaseNameRecent = txtDBName.Text; - Properties.Settings.Default.Save(); - } - - if (ReadAndExtract(txtLocalInstallPackage.Text, txtInstallBaseFolder.Text + "\\" + txtInstallSubFolder.Text + "\\Website")) - { - if (ModifyConfig()) - { - btnVisitSite.Visible = true; - } - } - } - } - else - { - RemoveDirectories(); - } - } - } + Directory.CreateDirectory(this.InstallFolder); + proceed = true; } } else { - MessageBox.Show("Please make sure you have entered a Database Server Name and a Database Name.", "Database Info", MessageBoxButtons.OK, MessageBoxIcon.Warning); + proceed = true; } - } - private bool CreateSiteInIIS() - { - try + if (proceed) { - //Create website in IIS - ServerManager iisManager = new ServerManager(); - var siteName = txtSiteNamePrefix.Text + txtSiteNameSuffix.Text; - var bindingInfo = "*:80:" + siteName; - string installFolder = txtInstallBaseFolder.Text.TrimEnd('\\') + "\\" + txtInstallSubFolder.Text; - - Boolean siteExists = SiteExists(siteName); - if (!siteExists) + if (!FileSystemController.DirectoryEmpty(this.InstallFolder)) { - Site mySite = iisManager.Sites.Add(siteName, "http", bindingInfo, installFolder + "\\Website"); - mySite.TraceFailedRequestsLogging.Enabled = true; - mySite.TraceFailedRequestsLogging.Directory = installFolder + "\\Logs"; - mySite.LogFile.Directory = installFolder + "\\Logs" + "\\W3svc" + mySite.Id.ToString(); + var result = DialogController.ShowMessage( + "Confirm Installation", + "All files and folders at this location will be deleted prior to installation of\nthe new DNN instance. Do you wish to proceed?", + SystemIcons.Information, + DialogController.DialogButtons.YesNo); - if (chkSiteSpecificAppPool.Checked) + if (result == DialogResult.No) { - var appPoolName = siteName + "_nvQuickSite"; - ApplicationPool newPool = iisManager.ApplicationPools.Add(appPoolName); - newPool.ManagedRuntimeVersion = "v4.0"; - mySite.ApplicationDefaults.ApplicationPoolName = appPoolName; + proceed = false; } - iisManager.CommitChanges(); - //MessageBox.Show("New DNN site (" + siteName + ") added sucessfully!", "Create Site", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - else - { - MessageBox.Show("Site name (" + siteName + ") already exists.", "Create Site", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - return true; - } - catch (Exception ex) - { - MessageBox.Show(ex.Message, "Create Site", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - } - - private bool SiteExists(string siteName) - { - Boolean flag = false; - ServerManager iisManager = new ServerManager(); - SiteCollection siteCollection = iisManager.Sites; - - foreach (Site site in siteCollection) - { - if (site.Name == siteName.ToString()) - { - flag = true; - if (chkDeleteSiteIfExists.Checked) + else { - if (site.ApplicationDefaults.ApplicationPoolName == siteName + "_nvQuickSite") - { - ApplicationPoolCollection appPools = iisManager.ApplicationPools; - foreach (ApplicationPool appPool in appPools) - { - if (appPool.Name == siteName + "_nvQuickSite") - { - iisManager.ApplicationPools.Remove(appPool); - break; - } - } - } - iisManager.Sites.Remove(site); - iisManager.CommitChanges(); - flag = false; - break; + proceed = true; } - break; } else { - flag = false; + proceed = true; } } - return flag; - } - - private bool UpdateHostsFile() - { - try - { - string hostsFile = Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\drivers\etc\hosts"; - var newEntry = "\t127.0.0.1 \t" + txtSiteNamePrefix.Text + txtSiteNameSuffix.Text; - if (!File.ReadAllLines(hostsFile).Contains(newEntry)) - { - if (File.ReadAllText(hostsFile).EndsWith(Environment.NewLine)) - { - using (StreamWriter w = File.AppendText(hostsFile)) - { - w.WriteLine(newEntry); - } - } - else - { - using (StreamWriter w = File.AppendText(hostsFile)) - { - w.WriteLine(Environment.NewLine + newEntry); - } - } - } - return true; - } - catch (Exception ex) + if (proceed) { - string errorMessage = ex.Message; - - if (errorMessage.IndexOf("is denied") > 0) - errorMessage += - "\r\r\nnvQuickSite is unable to add a new host entry to the above file. Please make sure the file is not read only. If it's not, make sure your antivirus software is not blocking changes made to the file. You can pause your antivirus software until nvQuickSite has completed its work, or add an exception for nvQuickSite in the antivirus software."; - - - MessageBox.Show("Error: " + errorMessage, "Update HOSTS File", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; + this.tabInstallPackage.Enabled = false; + this.tabSiteInfo.Enabled = false; + this.tabControl.TabPages.Insert(2, this.tabDatabaseInfo); + this.tabDatabaseInfo.Enabled = true; + this.tabProgress.Enabled = false; + this.tabControl.SelectedIndex = 2; + this.SaveUserSettings(); } } - private bool CreateDirectories() + private void rdoWindowsAuthentication_CheckedChanged(object sender, EventArgs e) { - try - { - string installFolder = txtInstallBaseFolder.Text + "\\" + txtInstallSubFolder.Text; - - var websiteDir = installFolder + "\\Website"; - var logsDir = installFolder + "\\Logs"; - var databaseDir = installFolder + "\\Database"; - - var appPoolName = @"IIS APPPOOL\DefaultAppPool"; - var dbServiceAccount = GetDBServiceAccount(); - var authenticatedUsers = GetAuthenticatedUsersAccount(); - - if (chkSiteSpecificAppPool.Checked) - { - appPoolName = @"IIS APPPOOL\" + txtSiteNamePrefix.Text + txtSiteNameSuffix.Text + "_nvQuickSite"; - } - - if (!Directory.Exists(websiteDir)) - { - Directory.CreateDirectory(websiteDir); - SetFolderPermission(appPoolName, websiteDir); - SetFolderPermission(authenticatedUsers, websiteDir); - } - else - { - Directory.Delete(websiteDir, true); - Directory.CreateDirectory(websiteDir); - SetFolderPermission(appPoolName, websiteDir); - SetFolderPermission(authenticatedUsers, websiteDir); - } - - if (!Directory.Exists(logsDir)) - { - Directory.CreateDirectory(logsDir); - SetFolderPermission(dbServiceAccount, logsDir); - SetFolderPermission(authenticatedUsers, logsDir); - } - else - { - Directory.Delete(logsDir, true); - Directory.CreateDirectory(logsDir); - SetFolderPermission(dbServiceAccount, logsDir); - SetFolderPermission(authenticatedUsers, logsDir); - } - - if (!Directory.Exists(databaseDir)) - { - Directory.CreateDirectory(databaseDir); - SetFolderPermission(dbServiceAccount, databaseDir); - SetFolderPermission(authenticatedUsers, databaseDir); - } - else - { - if (!DirectoryEmpty(databaseDir)) - { - var myDBFile = Directory.EnumerateFiles(databaseDir, "*.mdf").First().Split('_').First().Split('\\').Last(); - DropDatabase(myDBFile); - } - Directory.Delete(databaseDir); - Directory.CreateDirectory(databaseDir); - SetFolderPermission(dbServiceAccount, databaseDir); - SetFolderPermission(authenticatedUsers, databaseDir); - } - return true; - } - catch (Exception ex) - { - MessageBox.Show("Error: " + ex.Message, "Create Directories", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } + this.lblDBUserName.Enabled = false; + this.txtDBUserName.Enabled = false; + this.txtDBUserName.UseStyleColors = true; + this.lblDBPassword.Enabled = false; + this.txtDBPassword.Enabled = false; + this.txtDBPassword.UseStyleColors = true; } - private static string GetAuthenticatedUsersAccount() + private void rdoSQLServerAuthentication_CheckedChanged(object sender, EventArgs e) { - var sid = new System.Security.Principal.SecurityIdentifier("S-1-5-11"); //Authenticated Users - var account = sid.Translate(typeof(System.Security.Principal.NTAccount)); - return account.Value; + this.lblDBUserName.Enabled = true; + this.txtDBUserName.Enabled = true; + this.txtDBUserName.UseStyleColors = false; + this.lblDBPassword.Enabled = true; + this.txtDBPassword.Enabled = true; + this.txtDBPassword.UseStyleColors = false; } - private string GetDBServiceAccount() + private void btnDatabaseInfoBack_Click(object sender, EventArgs e) { - string dbServiceAccount = @"NT Service\MSSQLSERVER"; - string instanceName = txtDBServerName.Text.Trim(); - - if (instanceName.IndexOf(@"\") > -1) - { - dbServiceAccount = @"NT Service\MSSQL$" + instanceName.Substring(instanceName.LastIndexOf(@"\") + 1).ToUpper(); - } - - - return dbServiceAccount; + this.tabInstallPackage.Enabled = false; + this.tabSiteInfo.Enabled = true; + this.tabDatabaseInfo.Enabled = false; + this.tabControl.TabPages.Remove(this.tabDatabaseInfo); + this.tabControl.SelectedIndex = 1; } - private static void SetFolderPermission(String accountName, String folderPath) + private void btnDatabaseInfoNext_Click(object sender, EventArgs e) { - try - { - FileSystemRights Rights; - Rights = FileSystemRights.Modify; - bool modified; - var none = new InheritanceFlags(); - none = InheritanceFlags.None; - - var accessRule = new FileSystemAccessRule(accountName, Rights, none, PropagationFlags.NoPropagateInherit, AccessControlType.Allow); - var dInfo = new DirectoryInfo(folderPath); - var dSecurity = dInfo.GetAccessControl(); - dSecurity.ModifyAccessRule(AccessControlModification.Set, accessRule, out modified); - - var iFlags = new InheritanceFlags(); - iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; - - var accessRule2 = new FileSystemAccessRule(accountName, Rights, iFlags, PropagationFlags.InheritOnly, AccessControlType.Allow); - dSecurity.ModifyAccessRule(AccessControlModification.Add, accessRule2, out modified); - - dInfo.SetAccessControl(dSecurity); - } - catch (Exception ex) + if (string.IsNullOrWhiteSpace(this.txtDBServerName.Text) || string.IsNullOrWhiteSpace(this.txtDBName.Text)) { - MessageBox.Show("Error: " + ex.Message, "Set Folder Permissions", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } + DialogController.ShowMessage( + "Database Info", + "Please make sure you have entered a Database Server Name and\na Database Name.", + SystemIcons.Warning, + DialogController.DialogButtons.OK); - private void RemoveDirectories() - { - string installFolder = txtInstallBaseFolder.Text + "\\" + txtInstallSubFolder.Text; - - var websiteDir = installFolder + "\\Website"; - var logsDir = installFolder + "\\Logs"; - var databaseDir = installFolder + "\\Database"; - - Directory.Delete(websiteDir, true); - Directory.Delete(logsDir, true); - Directory.Delete(databaseDir); - } - - private bool CreateDatabase() - { - string myDBServerName = txtDBServerName.Text; - string connectionStringAuthSection = ""; - string connectionTimeout = "Connection Timeout=5;"; - if (rdoWindowsAuthentication.Checked) - { - connectionStringAuthSection = "Integrated Security=True;"; + return; } - else - { - connectionStringAuthSection = "User ID=" + txtDBUserName.Text + ";Password=" + txtDBPassword.Text + ";"; - } - - SqlConnection myConn = new SqlConnection("Server=" + myDBServerName + "; Initial Catalog=master;" + connectionStringAuthSection + connectionTimeout); - string myDBName = txtDBName.Text; - string installFolder = txtInstallBaseFolder.Text + "\\" + txtInstallSubFolder.Text; - - string str = "CREATE DATABASE [" + myDBName + "] ON PRIMARY " + - "(NAME = [" + myDBName + "_Data], " + - "FILENAME = '" + installFolder + "\\Database\\" + myDBName + "_Data.mdf', " + - "SIZE = 20MB, MAXSIZE = 200MB, FILEGROWTH = 10%) " + - "LOG ON (NAME = [" + myDBName + "_Log], " + - "FILENAME = '" + installFolder + "\\Database\\" + myDBName + "_Log.ldf', " + - "SIZE = 13MB, " + - "MAXSIZE = 50MB, " + - "FILEGROWTH = 10%)"; - - SqlCommand myCommand = new SqlCommand(str, myConn); try { - //if (CanConnectToDatabase(myDBServerName)) - //{ - myConn.Open(); - myCommand.ExecuteNonQuery(); - //MessageBox.Show("Database created successfully", "Create Database", MessageBoxButtons.OK, MessageBoxIcon.Information); - return true; - //} - //else - //{ - // MessageBox.Show("There was a problem connecting to the database. Please check the database name for accuracy.", "Create Database", MessageBoxButtons.OK, MessageBoxIcon.Warning); - // return false; - //} - } - catch (System.Exception ex) - { - MessageBox.Show("Error: " + ex.Message, "Create Database", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - finally - { - if (myConn.State == ConnectionState.Open) - { - myConn.Close(); - } - } - } + IISController.CreateSite( + this.SiteName, + this.InstallFolder, + this.chkSiteSpecificAppPool.Checked, + this.chkDeleteSiteIfExists.Checked); - static bool CanConnectToDatabase(string server) - { - bool returnVal = false; - try - { - if (server == "(local)") - { - server = "127.0.0.1"; - } - using (TcpClient tcpSocket = new TcpClient()) - { - AsyncCallback ConnectCallback = null; - IAsyncResult async = tcpSocket.BeginConnect(server, 1433, ConnectCallback, null); - DateTime startTime = DateTime.Now; - do - { - System.Threading.Thread.Sleep(500); - if (async.IsCompleted) break; - } while (DateTime.Now.Subtract(startTime).TotalSeconds < 5); - if (async.IsCompleted) - { - tcpSocket.EndConnect(async); - returnVal = true; - } - tcpSocket.Close(); - if (!async.IsCompleted) - { - returnVal = false; - } - } - return returnVal; - } - catch (SocketException ex) - { - MessageBox.Show("Error: " + ex.Message, "Database Connection", MessageBoxButtons.OK, MessageBoxIcon.Error); - return returnVal; - } - } + FileSystemController.UpdateHostsFile(this.SiteName); - private bool SetDatabasePermissions() - { - string myDBServerName = txtDBServerName.Text; - string connectionStringAuthSection = ""; - if (rdoWindowsAuthentication.Checked) - { - connectionStringAuthSection = "Integrated Security=True;"; - } - else - { - connectionStringAuthSection = "User ID=" + txtDBUserName.Text + ";Password=" + txtDBPassword.Text + ";"; - } + FileSystemController.CreateDirectories( + this.InstallFolder, + this.SiteName, + this.chkSiteSpecificAppPool.Checked, + this.txtDBServerName.Text.Trim(), + this.txtDBServerName.Text, + this.rdoWindowsAuthentication.Checked, + this.txtDBUserName.Text, + this.txtDBPassword.Text); - SqlConnection myConn = new SqlConnection("Server=" + myDBServerName + "; Initial Catalog=master;" + connectionStringAuthSection); + var databaseController = new DatabaseController( + this.txtDBName.Text, + this.txtDBServerName.Text, + this.rdoWindowsAuthentication.Checked, + this.txtDBUserName.Text, + this.txtDBPassword.Text, + this.InstallFolder, + this.chkSiteSpecificAppPool.Checked, + this.SiteName); + databaseController.CreateDatabase(); + databaseController.SetDatabasePermissions(); - string myDBName = txtDBName.Text; + this.tabInstallPackage.Enabled = false; + this.tabSiteInfo.Enabled = false; + this.tabDatabaseInfo.Enabled = false; + this.tabControl.TabPages.Insert(3, this.tabProgress); + this.tabProgress.Enabled = true; + this.lblProgress.Visible = true; + this.progressBar.Visible = true; + this.tabControl.SelectedIndex = 3; - var appPoolNameFull = @"IIS APPPOOL\DefaultAppPool"; - var appPoolName = "DefaultAppPool"; + this.SaveUserSettings(); - if (chkSiteSpecificAppPool.Checked) - { - appPoolNameFull = @"IIS APPPOOL\" + txtSiteNamePrefix.Text + txtSiteNameSuffix.Text + "_nvQuickSite"; - appPoolName = txtSiteNamePrefix.Text + txtSiteNameSuffix.Text + "_nvQuickSite"; - } + this.ReadAndExtract(this.txtLocalInstallPackage.Text, Path.Combine(this.txtInstallBaseFolder.Text, this.txtInstallSubFolder.Text, "Website")); + FileSystemController.ModifyConfig( + this.txtDBServerName.Text, + this.rdoWindowsAuthentication.Checked, + this.txtDBUserName.Text, + this.txtDBPassword.Text, + this.txtDBName.Text, + this.InstallFolder); - string str1 = "USE master"; - string str2 = "sp_grantlogin '" + appPoolNameFull + "'"; - string str3 = "USE [" + txtDBName.Text + "]"; - string str4 = "sp_grantdbaccess '" + appPoolNameFull + "', '" + appPoolName + "'"; - string str5 = "sp_addrolemember 'db_owner', '" + appPoolName + "'"; - - SqlCommand myCommand1 = new SqlCommand(str1, myConn); - SqlCommand myCommand2 = new SqlCommand(str2, myConn); - SqlCommand myCommand3 = new SqlCommand(str3, myConn); - SqlCommand myCommand4 = new SqlCommand(str4, myConn); - SqlCommand myCommand5 = new SqlCommand(str5, myConn); - try - { - myConn.Open(); - myCommand1.ExecuteNonQuery(); - myCommand2.ExecuteNonQuery(); - myCommand3.ExecuteNonQuery(); - myCommand4.ExecuteNonQuery(); - myCommand5.ExecuteNonQuery(); - //MessageBox.Show("Database created successfully", "Set Database Permissions", MessageBoxButtons.OK, MessageBoxIcon.Information); - return true; + this.btnVisitSite.Visible = true; + Log.Logger.Information("Site {siteName} ready to visit", this.SiteName); } - catch (System.Exception ex) + catch (SiteExistsException ex) { - MessageBox.Show(ex.Message, "Set Database Permissions", MessageBoxButtons.OK, MessageBoxIcon.Information); - return false; + DialogController.ShowMessage(ex.Source, ex.Message, SystemIcons.Warning, DialogController.DialogButtons.OK); } - finally + catch (IISControllerException ex) { - if (myConn.State == ConnectionState.Open) - { - myConn.Close(); - } + DialogController.ShowMessage(ex.Source, ex.Message, SystemIcons.Error, DialogController.DialogButtons.OK); } - } - - private void DropDatabase(string myDBName) - { - string myDBServerName = txtDBServerName.Text; - string connectionStringAuthSection = ""; - if (rdoWindowsAuthentication.Checked) + catch (FileSystemControllerException ex) { - connectionStringAuthSection = "Integrated Security=True;"; + DialogController.ShowMessage(ex.Source, ex.Message, SystemIcons.Error, DialogController.DialogButtons.OK); } - else + catch (DatabaseControllerException ex) { - connectionStringAuthSection = "User ID=" + txtDBUserName.Text + ";Password=" + txtDBPassword.Text + ";"; + DialogController.ShowMessage(ex.Source, ex.Message, SystemIcons.Error, DialogController.DialogButtons.OK); } - - SqlConnection myConn = new SqlConnection("Server=" + myDBServerName + "; Initial Catalog=master;" + connectionStringAuthSection); - - string str1 = @"USE master"; - string str2 = @"IF EXISTS(SELECT name FROM sys.databases WHERE name = '" + myDBName + "')" + - "DROP DATABASE [" + myDBName + "]"; - - SqlCommand myCommand1 = new SqlCommand(str1, myConn); - SqlCommand myCommand2 = new SqlCommand(str2, myConn); - try - { - myConn.Open(); - myCommand1.ExecuteNonQuery(); - myCommand2.ExecuteNonQuery(); - //MessageBox.Show("Database created successfully", "Create Database", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - catch (System.Exception ex) + catch (Exception ex) { - MessageBox.Show(ex.Message, "Drop Database", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - finally - { - if (myConn.State == ConnectionState.Open) - { - myConn.Close(); - } + DialogController.ShowMessage("Database Info Next", ex.Message, SystemIcons.Error, DialogController.DialogButtons.OK); + throw; } } - int fileCount; - long totalSize = 0, total = 0, lastVal = 0, sum = 0; - - public bool ReadAndExtract(string openPath, string savePath) + private void ReadAndExtract(string openPath, string savePath) { try { - fileCount = 0; - ZipFile myZip = new ZipFile(); - myZip = ZipFile.Read(openPath); + Log.Logger.Information("Extracting package"); + var myZip = ZipFile.Read(openPath); foreach (var entry in myZip) { - fileCount++; - totalSize += entry.UncompressedSize; + this.totalSize += entry.UncompressedSize; } - progressBar.Maximum = (Int32)totalSize; - myZip.ExtractProgress += new EventHandler(myZip_ExtractProgress); + + this.progressBar.Maximum = (int)this.totalSize; + myZip.ExtractProgress += new EventHandler(this.myZip_ExtractProgress); myZip.ExtractAll(savePath, ExtractExistingFileAction.OverwriteSilently); - lblProgressStatus.Text = "Congratulations! Your new site is now ready to visit!"; - return true; + this.lblProgressStatus.Text = "Congratulations! Your new site is now ready to visit!"; } catch (Exception ex) { - MessageBox.Show("Error: " + ex.Message, "Read And Extract Install Package", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; + var message = "Error attempting to read and extract the package"; + Log.Error(ex, message); + throw new ReadAndExtractException(message, ex) { Source = "Read And Extract Package" }; } + + Log.Logger.Information("Extracted package from {openPath} to {savePath}", openPath, savePath); } - void myZip_ExtractProgress(object sender, Ionic.Zip.ExtractProgressEventArgs e) + private void myZip_ExtractProgress(object sender, ExtractProgressEventArgs e) { System.Windows.Forms.Application.DoEvents(); - if (total != e.TotalBytesToTransfer) + if (this.total != e.TotalBytesToTransfer) { - sum += total - lastVal + e.BytesTransferred; - total = e.TotalBytesToTransfer; - lblProgressStatus.Text = "Copying: " + e.CurrentEntry.FileName; + this.sum += this.total - this.lastVal + e.BytesTransferred; + this.total = e.TotalBytesToTransfer; + this.lblProgressStatus.Text = "Copying: " + e.CurrentEntry.FileName; } else - sum += e.BytesTransferred - lastVal; - - lastVal = e.BytesTransferred; - - progressBar.Value = (Int32)sum; - } - - private bool ModifyConfig() - { - try { - string myDBServerName = txtDBServerName.Text; - string connectionStringAuthSection = ""; - if (rdoWindowsAuthentication.Checked) - { - connectionStringAuthSection = "Integrated Security=True;"; - } - else - { - connectionStringAuthSection = "User ID=" + txtDBUserName.Text + ";Password=" + txtDBPassword.Text + - ";"; - } - - string key = "SiteSqlServer"; - string value = @"Server=" + myDBServerName + ";Database=" + txtDBName.Text + ";" + - connectionStringAuthSection; - //string providerName = "System.Data.SqlClient"; - - string installFolder = txtInstallBaseFolder.Text + "\\" + txtInstallSubFolder.Text; - string path = installFolder + @"\Website\web.config"; - - var config = XDocument.Load(path); - var targetNode = config.Root.Element("connectionStrings").Element("add").Attribute("connectionString"); - targetNode.Value = value; - - var list = from appNode in config.Descendants("appSettings").Elements() - where appNode.Attribute("key").Value == key - select appNode; - - var e = list.FirstOrDefault(); - if (e != null) - { - e.Attribute("value").SetValue(value); - } - - config.Save(path); - return true; - } - catch (Exception ex) - { - MessageBox.Show("Error: " + ex.Message, "Modify Config", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; + this.sum += e.BytesTransferred - this.lastVal; } - } - #endregion + this.lastVal = e.BytesTransferred; - #region "Progress" + this.progressBar.Value = (int)this.sum; + } private void btnVisitSite_Click(object sender, EventArgs e) { - Process.Start("http://" + txtSiteNamePrefix.Text + txtSiteNameSuffix.Text); + var url = "http://" + this.SiteName; + Log.Logger.Information("Visiting {url}", url); + Process.Start(url); + Log.Logger.Information("Closing application"); Main.ActiveForm.Close(); } - #endregion - - #endregion - - #region "Tiles" - private void toggleSiteInfoRemember_CheckedChanged(object sender, EventArgs e) { Properties.Settings.Default.RememberFieldValues = !Properties.Settings.Default.RememberFieldValues; @@ -1129,18 +702,32 @@ private void tileDNNAwareness_Click(object sender, EventArgs e) private void tileQuickSettings_Click(object sender, EventArgs e) { - var userSettings = new UserSettings(); - var result = userSettings.ShowDialog(); - if (result == DialogResult.OK) + using (var userSettings = new UserSettings(this.loggingLevelSwitch)) { - Properties.Settings.Default.ShowReleaseCandidates = userSettings.ShowReleaseCandidates; - Properties.Settings.Default.ShareStatistics = userSettings.ShareStatistics; - Properties.Settings.Default.Save(); - LoadPackages(); + var result = userSettings.ShowDialog(); + if (result == DialogResult.OK) + { + Properties.Settings.Default.ShowReleaseCandidates = userSettings.ShowReleaseCandidates; + Properties.Settings.Default.ShareStatistics = userSettings.ShareStatistics; + Properties.Settings.Default.EnableLocalPackageInstall = userSettings.EnableLocalPackageInstall; + Properties.Settings.Default.Save(); + this.ReadUserSettings(); + this.LoadPackages(); + } } } - #endregion + private void btnViewExistingSites_Click(object sender, EventArgs e) + { + using (var viewExistingSites = new ViewExistingSites()) + { + viewExistingSites.ShowDialog(); + } + } + private void DownloadProgressLogTimer_Tick(object sender, EventArgs e) + { + Log.Logger.Information("Download progress {progress}%", this.progressBarDownload.Value); + } } } diff --git a/nvQuickSite/UserSettings.cs b/nvQuickSite/UserSettings.cs deleted file mode 100644 index fe95af9e..00000000 --- a/nvQuickSite/UserSettings.cs +++ /dev/null @@ -1,46 +0,0 @@ -//Copyright (c) 2016-2019 nvisionative, Inc. - -//This file is part of nvQuickSite. - -//nvQuickSite is free software: you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation, either version 3 of the License, or -//(at your option) any later version. - -//nvQuickSite is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the -//GNU General Public License for more details. - -//You should have received a copy of the GNU General Public License -//along with nvQuickSite. If not, see . - -using MetroFramework.Forms; - -namespace nvQuickSite -{ - public partial class UserSettings : MetroForm - { - public UserSettings() - { - InitializeComponent(); - lblMessage.Text = "User Settings"; - chkShowReleaseCandidates.Checked = Properties.Settings.Default.ShowReleaseCandidates; - chkShareStatistics.Checked = Properties.Settings.Default.ShareStatistics; - } - - public bool ShowReleaseCandidates - { - get { return chkShowReleaseCandidates.Checked; } - } - - public bool ShareStatistics - { - get { return chkShareStatistics.Checked; } - } - - //public string DialogMessage { get; set; } - - //public Image DialogIcon { get; set; } - } -} diff --git a/nvQuickSite/app.config b/nvQuickSite/app.config index c9fe6b2c..b7ac97f1 100644 --- a/nvQuickSite/app.config +++ b/nvQuickSite/app.config @@ -46,6 +46,12 @@ True + + + + + False + diff --git a/nvQuickSite/data/latestVersion.json b/nvQuickSite/data/latestVersion.json index e61e4d4f..5d4c4ea4 100644 --- a/nvQuickSite/data/latestVersion.json +++ b/nvQuickSite/data/latestVersion.json @@ -1,3 +1,3 @@ { - "latestVersion": "1.4.2" + "latestVersion": "2.0.0" } \ No newline at end of file diff --git a/nvQuickSite/nvQuickSite.GeneratedMSBuildEditorConfig.editorconfig b/nvQuickSite/nvQuickSite.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 00000000..755ee5e5 --- /dev/null +++ b/nvQuickSite/nvQuickSite.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,36 @@ +is_global = true +build_property.TargetFramework = +build_property.TargetFramework = +build_property.TargetFramework = +build_property.TargetFramework = +build_property.TargetFramework = +build_property.TargetPlatformMinVersion = +build_property.TargetPlatformMinVersion = +build_property.TargetPlatformMinVersion = +build_property.TargetPlatformMinVersion = +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.UsingMicrosoftNETSdkWeb = +build_property.UsingMicrosoftNETSdkWeb = +build_property.UsingMicrosoftNETSdkWeb = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.ProjectTypeGuids = +build_property.ProjectTypeGuids = +build_property.ProjectTypeGuids = +build_property.ProjectTypeGuids = +build_property.PublishSingleFile = +build_property.PublishSingleFile = +build_property.PublishSingleFile = +build_property.PublishSingleFile = +build_property.PublishSingleFile = +build_property.IncludeAllContentForSelfExtract = +build_property.IncludeAllContentForSelfExtract = +build_property.IncludeAllContentForSelfExtract = +build_property.IncludeAllContentForSelfExtract = +build_property.IncludeAllContentForSelfExtract = +build_property._SupportedPlatformList = +build_property._SupportedPlatformList = +build_property._SupportedPlatformList = +build_property._SupportedPlatformList = +build_property._SupportedPlatformList = diff --git a/nvQuickSite/nvQuickSite.csproj b/nvQuickSite/nvQuickSite.csproj index 28c22b95..810100b7 100644 --- a/nvQuickSite/nvQuickSite.csproj +++ b/nvQuickSite/nvQuickSite.csproj @@ -32,6 +32,7 @@ false true true + false AnyCPU @@ -43,6 +44,10 @@ prompt 4 false + false + + + bin\Debug\nvQuickSite.xml AnyCPU @@ -53,6 +58,9 @@ prompt 4 false + true + + 0A724629BFD7DFCC40A44BF2FB61D13E16ED4A93 @@ -102,22 +110,55 @@ - + + + + + + + + + - + Form - + + MsgBoxOk.cs + + + Form + + + MsgBoxYesNo.cs + + + + Form + + + DeleteSiteProgress.cs + + + Form + + + ViewExistingSites.cs + + + Form + + UserSettings.cs - + Form - + MsgBoxYesNoIgnore.cs @@ -135,10 +176,22 @@ - + + MsgBoxOk.cs + + + MsgBoxYesNo.cs + + + DeleteSiteProgress.cs + + + ViewExistingSites.cs + + UserSettings.cs - + MsgBoxYesNoIgnore.cs @@ -158,6 +211,7 @@ Resources.resx True + @@ -172,6 +226,7 @@ Settings.settings True + @@ -184,6 +239,7 @@ Always + @@ -215,6 +271,11 @@ 1.2.0.3 + + 3.3.1 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + 8.0.3 @@ -224,6 +285,23 @@ 1.0.0 + + 2.10.0 + + + 3.1.1 + + + 1.0.1 + + + 4.1.0 + + + 1.1.118 + runtime; build; native; contentfiles; analyzers; buildtransitive + all +