Commit c0dd7bdf3ea51fd1057af3af6546695e1620465b
1 parent
8d99b6cc
Add project files.
Showing
23 changed files
with
4394 additions
and
0 deletions
Show diff stats
| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | + | |
| 2 | +Microsoft Visual Studio Solution File, Format Version 12.00 | |
| 3 | +# Visual Studio Version 16 | |
| 4 | +VisualStudioVersion = 16.0.30804.86 | |
| 5 | +MinimumVisualStudioVersion = 10.0.40219.1 | |
| 6 | +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vrh.Log4Pro.MaintenanceConsole", "Vrh.Log4Pro.MaintenanceConsole\Vrh.Log4Pro.MaintenanceConsole.csproj", "{2AF86207-84E8-479F-A466-CA65C606B009}" | |
| 7 | +EndProject | |
| 8 | +Global | |
| 9 | + GlobalSection(SolutionConfigurationPlatforms) = preSolution | |
| 10 | + Debug|Any CPU = Debug|Any CPU | |
| 11 | + Release|Any CPU = Release|Any CPU | |
| 12 | + EndGlobalSection | |
| 13 | + GlobalSection(ProjectConfigurationPlatforms) = postSolution | |
| 14 | + {2AF86207-84E8-479F-A466-CA65C606B009}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |
| 15 | + {2AF86207-84E8-479F-A466-CA65C606B009}.Debug|Any CPU.Build.0 = Debug|Any CPU | |
| 16 | + {2AF86207-84E8-479F-A466-CA65C606B009}.Release|Any CPU.ActiveCfg = Release|Any CPU | |
| 17 | + {2AF86207-84E8-479F-A466-CA65C606B009}.Release|Any CPU.Build.0 = Release|Any CPU | |
| 18 | + EndGlobalSection | |
| 19 | + GlobalSection(SolutionProperties) = preSolution | |
| 20 | + HideSolutionNode = FALSE | |
| 21 | + EndGlobalSection | |
| 22 | + GlobalSection(ExtensibilityGlobals) = postSolution | |
| 23 | + SolutionGuid = {63445CF0-9B46-4509-A9DA-8F125390FDC2} | |
| 24 | + EndGlobalSection | |
| 25 | +EndGlobal | ... | ... |
| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<configuration> | |
| 3 | + <startup> | |
| 4 | + <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" /> | |
| 5 | + </startup> | |
| 6 | + <appSettings> | |
| 7 | + <add key="VRH.XmlParser:root" value="XmlParser.xml"/> | |
| 8 | + </appSettings> | |
| 9 | + <runtime> | |
| 10 | + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |
| 11 | + <dependentAssembly> | |
| 12 | + <assemblyIdentity name="System.Reflection.TypeExtensions" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> | |
| 13 | + <bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" /> | |
| 14 | + </dependentAssembly> | |
| 15 | + </assemblyBinding> | |
| 16 | + </runtime> | |
| 17 | +</configuration> | |
| 0 | 18 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,160 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8" ?> | |
| 2 | +<Configuration> | |
| 3 | + <XmlParser Description="Windows Services"> | |
| 4 | + <XmlVar Name="SERVICE_SYSSTART_NAME">VRH Starter for Log4ProIS</XmlVar> | |
| 5 | + <XmlVar Name="SERVICE_SYSSTART_DESC">System Starter Service for Log4ProIS System</XmlVar> | |
| 6 | + <XmlVar Name="SERVICE_SYSSTOP_NAME">VRH Terminator for Log4ProIS</XmlVar> | |
| 7 | + <XmlVar Name="SERVICE_SYSSTOP_DESC">System Terminator Service for Log4ProIS System</XmlVar> | |
| 8 | + <XmlVar Name="SERVICE_REDIS_NAME">VRH Redis for Log4ProIS</XmlVar> | |
| 9 | + <XmlVar Name="SERVICE_REDIS_DESC">Redis Monitor DataProvider Service for Log4ProIS System</XmlVar> | |
| 10 | + <XmlVar Name="SERVICE_ILOGGER_NAME">VRH iLogger for Log4ProIS</XmlVar> | |
| 11 | + <XmlVar Name="SERVICE_ILOGGER_DESC">iLogger Service for Log4ProIS System</XmlVar> | |
| 12 | + <XmlVar Name="SERVICE_ASEMWCP_NAME">VRH ASEMW for CP</XmlVar> | |
| 13 | + <XmlVar Name="SERVICE_ASEMWCP_DESC">ASE Middleware Service for Log4Pro CP System</XmlVar> | |
| 14 | + <XmlVar Name="SERVICE_ASEDCCP_NAME">VRH ASEDC for CP</XmlVar> | |
| 15 | + <XmlVar Name="SERVICE_ASEDCCP_DESC">ASEDC Service for Log4Pro CP System</XmlVar> | |
| 16 | +<!-- | |
| 17 | + <XmlVar Name="SERVICE_ASEMWALM_NAME">VRH ASEMW for ALM</XmlVar> | |
| 18 | + <XmlVar Name="SERVICE_ASEMWALM_DESC">ASE Middleware Service for Log4Pro ALM System</XmlVar> | |
| 19 | + <XmlVar Name="SERVICE_ASEDCALM_NAME">VRH ASEDC for ALM</XmlVar> | |
| 20 | + <XmlVar Name="SERVICE_ASEDCALM_DESC">ASEDC Service for Log4Pro ALM System</XmlVar> | |
| 21 | + <XmlVar Name="SERVICE_ASEDCASEMON1_NAME">VRH ASEDC ASEMON#1 for ALM</XmlVar> | |
| 22 | + <XmlVar Name="SERVICE_ASEDCASEMON1_DESC">ASEDC ASEMONITOR Service #1 for Log4Pro ALM System</XmlVar> | |
| 23 | + <XmlVar Name="SERVICE_ASEDCASEMON2_NAME">VRH ASEDC ASEMON#2 for ALM</XmlVar> | |
| 24 | + <XmlVar Name="SERVICE_ASEDCASEMON2_DESC">ASEDC ASEMONITOR Service #2 for Log4Pro ALM System</XmlVar> | |
| 25 | + <XmlVar Name="SERVICE_ACWDALM_NAME">VRH AC WD for ALM</XmlVar> | |
| 26 | + <XmlVar Name="SERVICE_ACWDALM_DESC">AC WatchDog Service for Log4Pro ALM System</XmlVar> | |
| 27 | + <XmlVar Name="SERVICE_ACIVCALM_NAME">VRH AC IVC for ALM</XmlVar> | |
| 28 | + <XmlVar Name="SERVICE_ACIVCALM_DESC">AC IVConnector Service for Log4Pro ALM System</XmlVar> | |
| 29 | + <XmlVar Name="SERVICE_ACISCHALM_NAME">VRH AC ISCH for ALM</XmlVar> | |
| 30 | + <XmlVar Name="SERVICE_ACISCHALM_DESC">AC IScheduler Service for Log4Pro ALM System</XmlVar> | |
| 31 | + <XmlVar Name="SERVICE_ACANDONALM_NAME">VRH AC ANDON for ALM</XmlVar> | |
| 32 | + <XmlVar Name="SERVICE_ACANDONALM_DESC">AC ANDON Service for Log4Pro ALM System</XmlVar> | |
| 33 | +--> | |
| 34 | + </XmlParser> | |
| 35 | + <XmlParser Description="WebApplications"> | |
| 36 | + <XmlVar Name="WEBANDONDESC">WebAndon Support Request Monitoring System</XmlVar> | |
| 37 | + <XmlVar Name="WEBALMDESC">WebALM Monitoring System</XmlVar> | |
| 38 | + <XmlVar Name="WEBPACKDESC">WebPack Packaging System</XmlVar> | |
| 39 | + <XmlVar Name="WEBLOG4PROISDESC">Log4ProIS WEB Application</XmlVar> | |
| 40 | + </XmlParser> | |
| 41 | + <XmlParser Description="Directories"> | |
| 42 | + <XmlVar Name="DIR_ROOT">C:\Log4ProIS</XmlVar> | |
| 43 | + <XmlVar Name="DIR_COMMONCONFIG">@DIR_ROOT@\CONFIG</XmlVar> | |
| 44 | + <XmlVar Name="DIR_SCRIPTS">@DIR_ROOT@\SERVICESCRIPTS</XmlVar> | |
| 45 | + <XmlVar Name="DIR_DESKTOPFOLDER">@Desktop@\WebPack Folders</XmlVar> | |
| 46 | + <XmlVar Name="DIR_ILOGMON">@DIR_ROOT@\Live Monitor</XmlVar> | |
| 47 | + | |
| 48 | + <XmlVar Name="DIR_STARTSTOPSYS">@DIR_ROOT@\VRH.StartStopSystem</XmlVar> | |
| 49 | + <XmlVar Name="DIR_REDIS">@DIR_ROOT@\Redis</XmlVar> | |
| 50 | + <XmlVar Name="DIR_REDISRDB">@DIR_REDIS@\rdb</XmlVar> | |
| 51 | + <XmlVar Name="DIR_ILOGGER">@DIR_ROOT@\VRH.iLogger</XmlVar> | |
| 52 | + <XmlVar Name="DIR_ILOGGERPLUGINS">@DIR_ILOGGER@\Plugins</XmlVar> | |
| 53 | + | |
| 54 | + <XmlVar Name="DIR_ASEEMU_CP">@DIR_ROOT@\ASEemu_CP</XmlVar> | |
| 55 | + <XmlVar Name="DIR_ASEMW_CP">@DIR_ROOT@\VRH.Log4Pro.ASEMW-DCWF_CP</XmlVar> | |
| 56 | + <XmlVar Name="DIR_ASEDC_CP">@DIR_ROOT@\VRH.Log4Pro.ASEDC-DCWF_CP</XmlVar> | |
| 57 | + | |
| 58 | + <XmlVar Name="DIR_ASEEMU_ALM">@DIR_ROOT@\ASEemu_ALM</XmlVar> | |
| 59 | + <XmlVar Name="DIR_ASEMW_ALM">@DIR_ROOT@\VRH.Log4Pro.ASEMW-DCWF_ALM</XmlVar> | |
| 60 | + <XmlVar Name="DIR_ASEDC_ALM">@DIR_ROOT@\VRH.Log4Pro.ASEDC-DCWF_ALM</XmlVar> | |
| 61 | + <XmlVar Name="DIR_ASEDC_ALMASEMON">@DIR_ROOT@\VRH.Log4Pro.ASEDC-ASEMON_ALM</XmlVar> | |
| 62 | + <XmlVar Name="DIR_AC_ALM">@DIR_ROOT@\VRH.Log4Pro.ACALM</XmlVar> | |
| 63 | + | |
| 64 | + <XmlVar Name="DIR_WEBAPPWEBPACK">@DIR_ROOT@\wwwroot_WebPack</XmlVar> | |
| 65 | + <XmlVar Name="DIR_WEBAPPWEBALM">@DIR_ROOT@\wwwroot_WebALM</XmlVar> | |
| 66 | + <XmlVar Name="DIR_WEBAPPWEBANDON">@DIR_ROOT@\wwwroot_WebAndon</XmlVar> | |
| 67 | + <XmlVar Name="DIR_WEBAPPLOG4PROIS">@DIR_ROOT@\wwwroot_Log4ProIS</XmlVar> | |
| 68 | + | |
| 69 | + <XmlVar Name="DIR_DB">@DIR_ROOT@\DB</XmlVar> | |
| 70 | + | |
| 71 | + <XmlVar Name="DIR_ROOTBAK">C:\Log4ProISBackups</XmlVar> | |
| 72 | + <XmlVar Name="MSMQTEST">@DIR_ROOTBAK@\MSMQtests</XmlVar> | |
| 73 | + <XmlVar Name="ILOG">@DIR_ROOTBAK@\VRH.Logfiles</XmlVar> | |
| 74 | + <XmlVar Name="REDISLOG">@ILOG@\RedisLog</XmlVar> | |
| 75 | + <XmlVar Name="WINEVENTLOGS">@ILOG@\WindowsEventLogs</XmlVar> | |
| 76 | + <XmlVar Name="DUMPFOLDER">@ILOG@\WindowsEventLogs</XmlVar> | |
| 77 | + <XmlVar Name="SRVLOG">@ILOG@\ServiceScriptLogs</XmlVar> | |
| 78 | + <XmlVar Name="DIR_SYSBAK">@DIR_ROOTBAK@\SystemBackups</XmlVar> | |
| 79 | + <XmlVar Name="DIR_DBBAK">@DIR_ROOTBAK@\BackupDBOnly</XmlVar> | |
| 80 | + <XmlVar Name="DIR_BAKTMP">@DIR_ROOTBAK@\TEMP</XmlVar> | |
| 81 | + <XmlVar Name="REPSCHSAV">@DIR_ROOTBAK@\ScheduledSavedReports</XmlVar> | |
| 82 | + <XmlVar Name="REPSAV">@DIR_ROOTBAK@\SavedReports</XmlVar> | |
| 83 | + <XmlVar Name="REPEXP">@DIR_ROOTBAK@\ExportDataReports</XmlVar> | |
| 84 | + <XmlVar Name="FTPDOWNLOAD" >@DIR_ROOTBAK@\FTPDownloads</XmlVar> | |
| 85 | + </XmlParser> | |
| 86 | + <XmlParser Description="Files"> | |
| 87 | + <XmlVar Name="SERVICESCRIPTCONFIG">@DIR_SCRIPTS@\ServiceScriptsConfig.xml</XmlVar> | |
| 88 | + <XmlVar Name="ILOGCONFIGFILE">@DIR_ILOGGERPLUGINS@\VRH.Common.iLogger.TextPlugin.dll.config</XmlVar> | |
| 89 | + <XmlVar Name="WEBPACKIDENTITYCONFIG">@DIR_WEBAPPWEBPACK@\WebIdentity.config</XmlVar> | |
| 90 | + <XmlVar Name="WEBALMIDENTITYCONFIG">@DIR_WEBAPPWEBALM@\WebIdentity.config</XmlVar> | |
| 91 | + <XmlVar Name="WEBANDONIDENTITYCONFIG">@DIR_WEBAPPWEBANDON@\WebIdentity.config</XmlVar> | |
| 92 | + <XmlVar Name="LOG4PROISIDENTITYCONFIG">@DIR_WEBAPPLOG4PROIS@\WebIdentity.config</XmlVar> | |
| 93 | + <XmlVar Name="REDISWINDOWSCONFIG">@DIR_REDIS@\redis.windows.conf</XmlVar> | |
| 94 | + </XmlParser> | |
| 95 | + | |
| 96 | + <WindowsServices> | |
| 97 | + | |
| 98 | + <WindowsService Name="@SERVICE_SYSSTART_NAME@" Description="@SERVICE_SYSSTART_DESC@" Exe="VRH.Empty.WindowsService.exe" Priority="Normal" StartMode="Automatic" | |
| 99 | + InstallDir="@DIR_STARTSTOPSYS@" RegistrationMode="standard" | |
| 100 | + DependOn="@SERVICE_ASEDCALM_NAME@,@SERVICE_ASEDCCP_NAME@,@SERVICE_ASEMWALM_NAME@,@SERVICE_ASEMWCP_NAME@,@SERVICE_ASEDCASEMON1_NAME@,@SERVICE_ASEDCASEMON2_NAME@,@SERVICE_ACIVCALM_NAME@,@SERVICE_ACISCHALM_NAME@,@SERVICE_ACANDONALM_NAME@,@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@"/> | |
| 101 | + | |
| 102 | + <WindowsService Name="@SERVICE_SYSSTOP_NAME@" Description="@SERVICE_SYSSTOP_DESC@" Exe="VRH.Empty.WindowsService.exe" | |
| 103 | + RegistrationMode="standard" DependOn="" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_STARTSTOPSYS@"/> | |
| 104 | + | |
| 105 | + <WindowsService Name="@SERVICE_REDIS_NAME@" Description="@SERVICE_REDIS_DESC@" Exe="redis-server.exe" | |
| 106 | + DependOn="@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_REDIS@" | |
| 107 | + RegistrationMode="redis" Arguments="C:\Log4ProIS\Redis\redis.windows.conf" UserName="LocalSystem" Password=""/> | |
| 108 | + | |
| 109 | + <WindowsService Name="@SERVICE_ILOGGER_NAME@" Description="@SERVICE_ILOGGER_DESC@" Exe="VRH.Common.iLogger.Topshelf.exe" | |
| 110 | + DependOn="@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_ILOGGER@" UserName="LocalSystem" Password="" | |
| 111 | + RegistrationMode="topshelf" Arguments="-APPCONFIG appconfigILOGGER.config" StartTimeout="10000" StopTimeOut="10000"/> | |
| 112 | + | |
| 113 | + <WindowsService Name="@SERVICE_ASEMWCP_NAME@" Description="@SERVICE_ASEMWCP_DESC@" Exe="VRH.Middleware.Topshelf.exe" | |
| 114 | + DependOn="@SERVICE_ILOGGER_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_ASEMW_CP@" UserName="LocalSystem" Password="" | |
| 115 | + RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigCP.config"/> | |
| 116 | + | |
| 117 | + <WindowsService Name="@SERVICE_ASEDCCP_NAME@" Description="@SERVICE_ASEDCCP_DESC@" Exe="VRH.Log4Pro.ASEDC.Topshelf.exe" | |
| 118 | + DependOn="@SERVICE_ASEMWCP_NAME@,@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" | |
| 119 | + InstallDir="@DIR_ASEDC_CP@" UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigDCWF_CP.config"/> | |
| 120 | + | |
| 121 | + <WindowsService Name="@SERVICE_ASEMWALM_NAME@" Description="@SERVICE_ASEMWALM_DESC@" Exe="VRH.Middleware.Topshelf.exe" | |
| 122 | + DependOn="@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_ASEMW_ALM@" | |
| 123 | + RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigALM.config" UserName="LocalSystem" Password=""/> | |
| 124 | + | |
| 125 | + <WindowsService Name="@SERVICE_ASEDCALM_NAME@" Description="@SERVICE_ASEDCALM_DESC@" Exe="VRH.Log4Pro.ASEDC.Topshelf.exe" | |
| 126 | + DependOn="@SERVICE_ASEMWALM_NAME@,@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" | |
| 127 | + InstallDir="@DIR_ASEDC_ALM@" UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigDCWF_ALM.config"/> | |
| 128 | + | |
| 129 | + <WindowsService Name="@SERVICE_ASEDCASEMON1_NAME@" Description="@SERVICE_ASEDCASEMON1_DESC@" Exe="VRH.Log4Pro.ASEDC.Topshelf.exe" | |
| 130 | + DependOn="@SERVICE_ASEMWALM_NAME@,@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" | |
| 131 | + InstallDir="@DIR_ASEDC_ALMASEMON@" UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigASEMON_ALM.config -INUSEBY:HDMI1"/> | |
| 132 | + | |
| 133 | + <WindowsService Name="@SERVICE_ASEDCASEMON2_NAME@" Description="@SERVICE_ASEDCASEMON2_DESC@" Exe="VRH.Log4Pro.ASEDC.Topshelf.exe" | |
| 134 | + DependOn="@SERVICE_ASEMWALM_NAME@,@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" | |
| 135 | + InstallDir="@DIR_ASEDC_ALMASEMON@" UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigASEMON_ALM.config -INUSEBY:HDMI2"/> | |
| 136 | + | |
| 137 | + <WindowsService Name="@SERVICE_ACWDALM_NAME@" Description="@SERVICE_ACWDALM_DESC@" Exe="Vrh.ApplicationContainer.Topshelf.exe" | |
| 138 | + DependOn="@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" | |
| 139 | + InstallDir="@DIR_AC_ALM@" UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigWD.config -INUSEBY:WD"/> | |
| 140 | + | |
| 141 | + <WindowsService Name="@SERVICE_ACIVCALM_NAME@" Description="@SERVICE_ACIVCALM_DESC@" Exe="Vrh.ApplicationContainer.Topshelf.exe" | |
| 142 | + DependOn="@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_AC_ALM@" | |
| 143 | + UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigIVC.config -INUSEBY:IVC"/> | |
| 144 | + | |
| 145 | + <WindowsService Name="@SERVICE_ACISCHALM_NAME@" Description="@SERVICE_ACISCHALM_DESC@" Exe="Vrh.ApplicationContainer.Topshelf.exe" | |
| 146 | + DependOn="@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_AC_ALM@" | |
| 147 | + UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigISCH.config -INUSEBY:ISCH"/> | |
| 148 | + | |
| 149 | + <WindowsService Name="@SERVICE_ACANDONALM_NAME@" Description="@SERVICE_ACANDONALM_DESC@" Exe="Vrh.ApplicationContainer.Topshelf.exe" | |
| 150 | + DependOn="@SERVICE_REDIS_NAME@,@SERVICE_ILOGGER_NAME@,@SERVICE_SYSSTOP_NAME@" Priority="Normal" StartMode="Automatic" InstallDir="@DIR_AC_ALM@" | |
| 151 | + UserName="LocalSystem" Password="" RegistrationMode="topshelf" Arguments="-APPCONFIG:appconfigANDON.config -INUSEBY:ANDON"/> | |
| 152 | + </WindowsServices> | |
| 153 | + | |
| 154 | + <WebApplications> | |
| 155 | + <WebApplication Id="WEBAPP_ANDON" Name="WebAndon" Description="@WEBANDONDESC@" AppPool="WebAndon" Website="Default Web Site" InstallDir="@DIR_WEBAPPWEBANDON@" SiteRootDir="@DIR_WEBAPPWEBANDON@" IdentityConfigFile="@WEBANDONIDENTITYCONFIG@" AppPoolUsername="" AppPoolPassword="" AppPoolPipeLineMode="" RecreateSite="false" RecreatePool="true" RecreateApp="true"/> | |
| 156 | + <WebApplication Id="WEBAPP_ALM" Name="WebALM" Description="@WEBALMDESC@" AppPool="WebALM" Website="Default Web Site" InstallDir="@DIR_WEBAPPWEBALM@" SiteRootDir="@DIR_WEBAPPWEBALM@" IdentityConfigFile="@WEBALMIDENTITYCONFIG@" AppPoolUsername="" AppPoolPassword="" AppPoolPipeLineMode="" RecreateSite="false" RecreatePool="true" RecreateApp="true"/> | |
| 157 | + <WebApplication Id="WEBAPP_CP" Name="WebPack" Description="@WEBPACKDESC@" AppPool="WebPack" Website="Default Web Site" InstallDir="@DIR_WEBAPPWEBPACK@" SiteRootDir="@DIR_WEBAPPWEBPACK@" IdentityConfigFile="@WEBPACKIDENTITYCONFIG@" AppPoolUsername="" AppPoolPassword="" AppPoolPipeLineMode="" RecreateSite="false" RecreatePool="true" RecreateApp="true"/> | |
| 158 | + <WebApplication Id="WEBAPP_LOG4PROIS" Name="Log4ProIS" Description="@WEBLOG4PROISDESC@" AppPool="Log4ProIS" Website="Default Web Site" InstallDir="@DIR_WEBAPPLOG4PROIS@" SiteRootDir="@DIR_WEBAPPLOG4PROIS@" IdentityConfigFile="@LOG4PROISIDENTITYCONFIG@" AppPoolUsername="" AppPoolPassword="" AppPoolPipeLineMode="" RecreateSite="false" RecreatePool="true" RecreateApp="true"/> | |
| 159 | + </WebApplications> | |
| 160 | +</Configuration> | |
| 0 | 161 | \ No newline at end of file | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - ColorConsole.cs
0 → 100644
| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Linq; | |
| 4 | +using System.Text; | |
| 5 | +using System.Threading.Tasks; | |
| 6 | + | |
| 7 | +using Microsoft.Web.Administration; | |
| 8 | +using System.Management; | |
| 9 | +using System.Diagnostics; | |
| 10 | + | |
| 11 | +using Vrh.XmlProcessing; | |
| 12 | +using System.Xml.Linq; | |
| 13 | + | |
| 14 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
| 15 | +{ | |
| 16 | + #region ColorConsole | |
| 17 | + public static class ColorConsole | |
| 18 | + { | |
| 19 | + public static string WideString(string txt) | |
| 20 | + { | |
| 21 | + if (txt == null) { return null; }; | |
| 22 | + if (txt == "") { return " "; }; | |
| 23 | + string widetxt = null; | |
| 24 | + for (var i = 0; i < txt.Length; i++) { widetxt += txt[i] + " "; }; | |
| 25 | + return widetxt.Substring(0, widetxt.Length - 1); | |
| 26 | + } | |
| 27 | + | |
| 28 | + public static string ReadLine(string text = null, ConsoleColor? f = null, ConsoleColor? b = null, string bracket = null, string prefix = "") | |
| 29 | + { | |
| 30 | + Write(text, f, b,bracket,prefix); | |
| 31 | + return Console.ReadLine(); | |
| 32 | + } | |
| 33 | + public static void WriteLine(string text = null, ConsoleColor? f = null, ConsoleColor? b = null, string bracket = null,string prefix="", string suffix = "") | |
| 34 | + { | |
| 35 | + Write(text, f, b, bracket,prefix,suffix); | |
| 36 | + Console.WriteLine(); | |
| 37 | + } | |
| 38 | + public static void Write(string text = null, ConsoleColor? f = null, ConsoleColor? b = null, string bracket = null, string prefix = "",string suffix="") | |
| 39 | + { | |
| 40 | + if (!string.IsNullOrEmpty(prefix)) { Write(prefix); } | |
| 41 | + if (!string.IsNullOrEmpty(bracket) && bracket.Length==1) { bracket = bracket + bracket; } | |
| 42 | + if (!string.IsNullOrEmpty(bracket)) { Console.Write($"{bracket[0]}"); } | |
| 43 | + ConsoleColor savecolorF = Console.ForegroundColor; | |
| 44 | + ConsoleColor savecolorB = Console.BackgroundColor; | |
| 45 | + if (f != null) { Console.ForegroundColor = (ConsoleColor)f; } | |
| 46 | + if (b != null) { Console.BackgroundColor = (ConsoleColor)b; } | |
| 47 | + if (text != null) { Console.Write($"{text}"); } | |
| 48 | + Console.ForegroundColor = savecolorF; | |
| 49 | + Console.BackgroundColor = savecolorB; | |
| 50 | + if (!string.IsNullOrEmpty(bracket)) { Console.Write($"{bracket[1]}"); } | |
| 51 | + if (!string.IsNullOrEmpty(prefix)) { Write(suffix); } | |
| 52 | + } | |
| 53 | + } | |
| 54 | + #endregion ColorConsole | |
| 55 | +} | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs
0 → 100644
| ... | ... | @@ -0,0 +1,179 @@ |
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Linq; | |
| 4 | +using System.Text; | |
| 5 | +using System.Threading.Tasks; | |
| 6 | + | |
| 7 | +using Microsoft.Web.Administration; | |
| 8 | +using System.Management; | |
| 9 | +using System.Diagnostics; | |
| 10 | + | |
| 11 | +using Vrh.XmlProcessing; | |
| 12 | +using System.Xml.Linq; | |
| 13 | + | |
| 14 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
| 15 | +{ | |
| 16 | + #region CommandLineParser | |
| 17 | + public static class CommandLineParser | |
| 18 | + { | |
| 19 | + public static string Quote(this string txt) { return $"\"{txt.EscapeQuotes()}\""; } | |
| 20 | + public static string QuoteS(this string txt) { return $"'{txt.EscapeQuotes("'")}'"; } | |
| 21 | + private static string EscapeQuotes(this string txt,string quotestr="\"") | |
| 22 | + { | |
| 23 | + string escapedtxt = txt.Replace("\"", "\\\""); | |
| 24 | + | |
| 25 | + return escapedtxt; ; | |
| 26 | + } | |
| 27 | + | |
| 28 | + public static IEnumerable<string> SplitArgs(string commandLine) | |
| 29 | + { | |
| 30 | + var result = new StringBuilder(); | |
| 31 | + | |
| 32 | + var quoted = false; | |
| 33 | + var escaped = false; | |
| 34 | + var started = false; | |
| 35 | + var allowcaret = false; | |
| 36 | + for (int i = 0; i < commandLine.Length; i++) | |
| 37 | + { | |
| 38 | + var chr = commandLine[i]; | |
| 39 | + | |
| 40 | + if (chr == '^' && !quoted) | |
| 41 | + { | |
| 42 | + if (allowcaret) | |
| 43 | + { | |
| 44 | + result.Append(chr); | |
| 45 | + started = true; | |
| 46 | + escaped = false; | |
| 47 | + allowcaret = false; | |
| 48 | + } | |
| 49 | + else if (i + 1 < commandLine.Length && commandLine[i + 1] == '^') | |
| 50 | + { | |
| 51 | + allowcaret = true; | |
| 52 | + } | |
| 53 | + else if (i + 1 == commandLine.Length) | |
| 54 | + { | |
| 55 | + result.Append(chr); | |
| 56 | + started = true; | |
| 57 | + escaped = false; | |
| 58 | + } | |
| 59 | + } | |
| 60 | + else if (escaped) | |
| 61 | + { | |
| 62 | + result.Append(chr); | |
| 63 | + started = true; | |
| 64 | + escaped = false; | |
| 65 | + } | |
| 66 | + else if (chr == '"') | |
| 67 | + { | |
| 68 | + quoted = !quoted; | |
| 69 | + started = true; | |
| 70 | + } | |
| 71 | + else if (chr == '\\' && i + 1 < commandLine.Length && commandLine[i + 1] == '"') | |
| 72 | + { | |
| 73 | + escaped = true; | |
| 74 | + } | |
| 75 | + else if (chr == ' ' && !quoted) | |
| 76 | + { | |
| 77 | + if (started) yield return result.ToString(); | |
| 78 | + result.Clear(); | |
| 79 | + started = false; | |
| 80 | + } | |
| 81 | + else | |
| 82 | + { | |
| 83 | + result.Append(chr); | |
| 84 | + started = true; | |
| 85 | + } | |
| 86 | + } | |
| 87 | + | |
| 88 | + if (started) yield return result.ToString(); | |
| 89 | + } | |
| 90 | + public static void UnitTest() | |
| 91 | + { | |
| 92 | + Test(1,"One", new[] { "One" }); | |
| 93 | + Test(2,"One ", new[] { "One" }); | |
| 94 | + Test(3," One", new[] { "One" }); | |
| 95 | + Test(4," One ", new[] { "One" }); | |
| 96 | + Test(5,"One Two", new[] { "One", "Two" }); | |
| 97 | + Test(6,"One Two", new[] { "One", "Two" }); | |
| 98 | + Test(7,"One Two", new[] { "One", "Two" }); | |
| 99 | + Test(8,"\"One Two\"", new[] { "One Two" }); | |
| 100 | + Test(9,"One \"Two Three\"", new[] { "One", "Two Three" }); | |
| 101 | + Test(10,"One \"Two Three\" Four", new[] { "One", "Two Three", "Four" }); | |
| 102 | + Test(11,"One=\"Two Three\" Four", new[] { "One=Two Three", "Four" }); | |
| 103 | + Test(12, "One\"", new[] { "One" }); | |
| 104 | + Test(13,"One\"Two Three\" Four", new[] { "OneTwo Three", "Four" }); | |
| 105 | + Test(14,"One\"Two Three Four", new[] { "OneTwo Three Four" }); | |
| 106 | + Test(15,"\"One Two\"", new[] { "One Two" }); | |
| 107 | + Test(16,"One\" \"Two", new[] { "One Two" }); | |
| 108 | + Test(17,"\"One\" \"Two\"", new[] { "One", "Two" }); | |
| 109 | + Test(18,"One\\\" Two", new[] { "One\"", "Two" }); | |
| 110 | + Test(19,"\\\"One\\\" Two", new[] { "\"One\"", "Two" }); | |
| 111 | + Test(20,"\"One", new[] { "One" }); | |
| 112 | + Test(21,"One \"\"", new[] { "One", "" }); | |
| 113 | + Test(22,"One \"", new[] { "One", "" }); | |
| 114 | + Test(23,"1 A=\"B C\"=D 2", new[] { "1", "A=B C=D", "2" }); | |
| 115 | + Test(24,"1 A=\"B \\\" C\"=D 2", new[] { "1", "A=B \" C=D", "2" }); | |
| 116 | + Test(25,"1 \\A 2", new[] { "1", "\\A", "2" }); | |
| 117 | + Test(26,"1 \\\" 2", new[] { "1", "\"", "2" }); | |
| 118 | + Test(27,"1 \\\\\" 2", new[] { "1", "\\\"", "2" }); | |
| 119 | + Test(28,"\"", new[] { "" }); | |
| 120 | + Test(29,"\\\"", new[] { "\"" }); | |
| 121 | + Test(30,"'A B'", new[] { "'A", "B'" }); | |
| 122 | + Test(31,"^", new[] { "^" }); | |
| 123 | + Test(32,"^A", new[] { "A" }); | |
| 124 | + Test(33,"^^", new[] { "^" }); | |
| 125 | + Test(34,"\\^^", new[] { "\\^" }); | |
| 126 | + Test(35,"^\\\\", new[] { "\\\\" }); | |
| 127 | + Test(36,"^\"A B\"", new[] { "A B" }); | |
| 128 | + Test(37,@"/src:""C:\tmp\Some Folder\Sub Folder"" /users:""abcdefg@hijkl.com"" tasks:""SomeTask,Some Other Task"" -someParam foo", new[] { @"/src:C:\tmp\Some Folder\Sub Folder", @"/users:abcdefg@hijkl.com", @"tasks:SomeTask,Some Other Task", @"-someParam", @"foo" }); | |
| 129 | + Test(38,"", new string[] { }); | |
| 130 | + Test(39,"a", new[] { "a" }); | |
| 131 | + Test(40," abc ", new[] { "abc" }); | |
| 132 | + Test(41,"a b ", new[] { "a", "b" }); | |
| 133 | + Test(42,"a b \"c d\"", new[] { "a", "b", "c d" }); | |
| 134 | + Test(43,"this is a test ", new[] { "this", "is", "a", "test" }); | |
| 135 | + Test(44,"this \"is a\" test", new[] { "this", "is a", "test" }); | |
| 136 | + Test(45,"\"C:\\Program Files\"", new[] { "C:\\Program Files" }); | |
| 137 | + Test(46,"\"He whispered to her \\\"I love you\\\".\"", new[] { "He whispered to her \"I love you\"." }); | |
| 138 | + Console.WriteLine("Press a key to continue...."); | |
| 139 | + Console.ReadKey(); | |
| 140 | + } | |
| 141 | + static void Test(int id,string cmd, string[] r) | |
| 142 | + { | |
| 143 | + string scmd="",sexp=""; | |
| 144 | + try | |
| 145 | + { | |
| 146 | + var sr = SplitArgs(cmd).ToArray(); | |
| 147 | + scmd = "["+String.Join("][", sr)+"]"; | |
| 148 | + sexp = "[" + String.Join("][", r) + "]"; | |
| 149 | + if (r.Length != sr.Length) | |
| 150 | + { | |
| 151 | + | |
| 152 | + Console.WriteLine($"ERROR:{id}"); | |
| 153 | + Console.WriteLine($" cmdline : {cmd}"); | |
| 154 | + Console.WriteLine($" splitted: {scmd}"); | |
| 155 | + Console.WriteLine($" expected: {sexp}"); | |
| 156 | + return; | |
| 157 | + } | |
| 158 | + for (int i = 0; i < r.Length; i++) | |
| 159 | + if (r[i] != sr[i]) | |
| 160 | + { | |
| 161 | + Console.WriteLine($"ERROR:{id}"); | |
| 162 | + Console.WriteLine($" cmdline : {cmd}"); | |
| 163 | + Console.WriteLine($" splitted: {scmd}"); | |
| 164 | + Console.WriteLine($" expected: {sexp}"); | |
| 165 | + return; | |
| 166 | + } | |
| 167 | + } | |
| 168 | + catch (Exception ex) | |
| 169 | + { | |
| 170 | + Console.WriteLine($"EXCEP:{id}"); | |
| 171 | + Console.WriteLine($" cmdline : {cmd}"); | |
| 172 | + Console.WriteLine($" splitted: {scmd}"); | |
| 173 | + Console.WriteLine($" expected: {sexp}"); | |
| 174 | + return; | |
| 175 | + } | |
| 176 | + } | |
| 177 | + } | |
| 178 | + #endregion CommandLineParser | |
| 179 | +} | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs
0 → 100644
| ... | ... | @@ -0,0 +1,289 @@ |
| 1 | +using System; | |
| 2 | +using System.IO; | |
| 3 | +using System.Collections.Generic; | |
| 4 | +using System.Linq; | |
| 5 | +using System.Text; | |
| 6 | +using System.Threading.Tasks; | |
| 7 | +using System.Threading; | |
| 8 | + | |
| 9 | +using Microsoft.Web.Administration; | |
| 10 | +using System.Management; | |
| 11 | +using System.Diagnostics; | |
| 12 | + | |
| 13 | +using Vrh.XmlProcessing; | |
| 14 | +using System.Xml.Linq; | |
| 15 | + | |
| 16 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
| 17 | +{ | |
| 18 | + public class Menu | |
| 19 | + { | |
| 20 | + public delegate Object MenuItemExecutorFunc(Object p, Object o); | |
| 21 | + public delegate Object MenuItemDisplayerFunc(Object p, int i); | |
| 22 | + public Menu(string title, string selectionprompt = null) { Title = title; if (!string.IsNullOrWhiteSpace(selectionprompt)) { SelectionPrompt = selectionprompt; } } | |
| 23 | + #region private fields | |
| 24 | + private string title; | |
| 25 | + private string Title { get { return ColorConsole.WideString(title); } set { title = value; } } | |
| 26 | + private MenuItemDisplayerFunc MenuItemDisplayer; | |
| 27 | + private SelectionMode selectionMode = Menu.SelectionMode.Multi; | |
| 28 | + private int HeaderWidth = 9; | |
| 29 | + private string SelectionPrompt = "Make Your selection!"; | |
| 30 | + #endregion private fields | |
| 31 | + | |
| 32 | + #region public properties | |
| 33 | + public List<Item> MenuItemList { get; private set; } = new List<Item>(); | |
| 34 | + List<string> MenuKeyList { get { return MenuItemList.Select(x => x.Key).ToList(); } } | |
| 35 | + #endregion public properties | |
| 36 | + | |
| 37 | + #region public tools | |
| 38 | + public Menu SetMenuItemDisplayer(MenuItemDisplayerFunc displayer) | |
| 39 | + { | |
| 40 | + MenuItemDisplayer = displayer; | |
| 41 | + return this; | |
| 42 | + } | |
| 43 | + public Menu SetSelectionMode(SelectionMode sm) { selectionMode = sm; return this; } | |
| 44 | + public Menu SetHeaderWidth(int hw) { HeaderWidth= hw; return this; } | |
| 45 | + public Menu AddMenuItem(Item mi) | |
| 46 | + { | |
| 47 | + MenuItemList.Add(mi); | |
| 48 | + if (string.IsNullOrWhiteSpace(mi.Key)) { mi.Key = $"#$KEY{MenuItemList.IndexOf(mi)}"; } | |
| 49 | + return this; | |
| 50 | + } | |
| 51 | + public void ClearMenuItemList() { MenuItemList.Clear(); } | |
| 52 | + public void ExecuteMenu() | |
| 53 | + { | |
| 54 | + try | |
| 55 | + { | |
| 56 | + while (true) | |
| 57 | + { | |
| 58 | + DisplayTitle(); | |
| 59 | + DisplayItems(); | |
| 60 | + var sr = Select(); | |
| 61 | + if (sr.Result == Menu.SelectionResult.Exit) { return; } | |
| 62 | + else if (sr.Result == Menu.SelectionResult.None) { continue; } | |
| 63 | + else if (sr.Result == Menu.SelectionResult.Error) { continue; } | |
| 64 | + Execute(sr.SelectedKeyList); | |
| 65 | + } | |
| 66 | + } | |
| 67 | + catch (Exception ex) | |
| 68 | + { | |
| 69 | + ColorConsole.WriteLine(ex.Message,ConsoleColor.Red); | |
| 70 | + if (ex.InnerException != null) { ColorConsole.WriteLine(ex.InnerException.Message, ConsoleColor.Red); } | |
| 71 | + ColorConsole.WriteLine("Press any key to continue..."); | |
| 72 | + } | |
| 73 | + } | |
| 74 | + public void DisplayTitle() | |
| 75 | + { | |
| 76 | + Console.Clear(); | |
| 77 | + ColorConsole.WriteLine(Title, ConsoleColor.White); | |
| 78 | + ColorConsole.WriteLine(new string('-', Title.Length)); | |
| 79 | + } | |
| 80 | + public void DisplayItems(int columns = 1, int columnlength = 0) | |
| 81 | + { | |
| 82 | + int columncounter = 0; | |
| 83 | + ColorConsole.WriteLine(); | |
| 84 | + var i = 1; | |
| 85 | + Console.SetCursorPosition(0, Console.CursorTop); | |
| 86 | + foreach (var menuitem in MenuItemList) | |
| 87 | + { | |
| 88 | + ColorConsole.Write($"["); | |
| 89 | + ColorConsole.Write($"{i}"); | |
| 90 | + if (!string.IsNullOrEmpty(menuitem.Key) && !menuitem.Key.StartsWith("#$KEY")) | |
| 91 | + { | |
| 92 | + ColorConsole.Write($":"); | |
| 93 | + ColorConsole.Write(menuitem.Key, ConsoleColor.Yellow); | |
| 94 | + } | |
| 95 | + ColorConsole.Write($"]"); | |
| 96 | + Console.SetCursorPosition(columnlength * columncounter+HeaderWidth, Console.CursorTop); | |
| 97 | + | |
| 98 | + if (!string.IsNullOrEmpty(menuitem.Text)) | |
| 99 | + { | |
| 100 | + ColorConsole.Write(menuitem.Text); | |
| 101 | + } | |
| 102 | + if (columns == 1) | |
| 103 | + { | |
| 104 | + if (!string.IsNullOrEmpty(menuitem.Text)) { ColorConsole.WriteLine(); } | |
| 105 | + if (MenuItemDisplayer != null) | |
| 106 | + { | |
| 107 | + for (var li = 0; li < 100; li++) | |
| 108 | + { | |
| 109 | + if (li>0) { ColorConsole.Write(new string(' ',HeaderWidth)); } | |
| 110 | + var str = (string)MenuItemDisplayer(menuitem.Parameters, li); | |
| 111 | + if (string.IsNullOrEmpty(str)) { Console.SetCursorPosition(0, Console.CursorTop); } | |
| 112 | + if (str == null) { break; } | |
| 113 | + } | |
| 114 | + } | |
| 115 | + } | |
| 116 | + else | |
| 117 | + { | |
| 118 | + columncounter++; | |
| 119 | + if (columncounter == columns) { ColorConsole.WriteLine(); columncounter = 0; } | |
| 120 | + else | |
| 121 | + { | |
| 122 | + Console.SetCursorPosition(columnlength * columncounter - 2, Console.CursorTop); | |
| 123 | + ColorConsole.Write(" "); | |
| 124 | + } | |
| 125 | + } | |
| 126 | + i++; | |
| 127 | + } | |
| 128 | + if (columns != 1) { ColorConsole.WriteLine(); } | |
| 129 | + if (selectionMode==SelectionMode.Multi) | |
| 130 | + { | |
| 131 | + ColorConsole.Write("*", ConsoleColor.Red,bracket:"()");ColorConsole.WriteLine(" All"); | |
| 132 | + } | |
| 133 | + ColorConsole.Write("EX", ConsoleColor.Red,bracket:"()");ColorConsole.WriteLine(" Exit"); | |
| 134 | + } | |
| 135 | + public class Selection | |
| 136 | + { | |
| 137 | + public List<string> SelectedKeyList = null; | |
| 138 | + public SelectionResult Result; | |
| 139 | + public List<object> SelectedParameterList; | |
| 140 | + } | |
| 141 | + public enum SelectionResult { Exit, None, Error, Ok, } | |
| 142 | + public enum SelectionMode { Single, Multi, } | |
| 143 | + public Selection Select() | |
| 144 | + { | |
| 145 | + List<string> selectionKeyList=null; | |
| 146 | + List<object> selectionParList = null; | |
| 147 | + var result = new Selection(); | |
| 148 | + string selectionliststr; | |
| 149 | + ColorConsole.Write(SelectionPrompt,ConsoleColor.Yellow); | |
| 150 | + ColorConsole.Write(" --> ", ConsoleColor.White); | |
| 151 | + var remembercursorleft = Console.CursorLeft; | |
| 152 | + var remembercursortop = Console.CursorTop; | |
| 153 | + if (selectionMode == SelectionMode.Multi) | |
| 154 | + { | |
| 155 | + ColorConsole.WriteLine(); | |
| 156 | + ColorConsole.WriteLine("Multiple selections are separated with comma(,), enter asterisk(*) to select all)!"); | |
| 157 | + } | |
| 158 | + var remembercursorleft2 = Console.CursorLeft; | |
| 159 | + var remembercursortop2 = Console.CursorTop; | |
| 160 | + Console.SetCursorPosition(remembercursorleft, remembercursortop); | |
| 161 | + selectionliststr = Console.ReadLine().ToUpper(); | |
| 162 | + if (selectionMode == SelectionMode.Multi) | |
| 163 | + { | |
| 164 | + Console.SetCursorPosition(remembercursorleft2, remembercursortop2); | |
| 165 | + } | |
| 166 | + if (selectionliststr == "EX") | |
| 167 | + { | |
| 168 | + result.Result = SelectionResult.Exit; | |
| 169 | + result.SelectedKeyList = null; | |
| 170 | + return result; | |
| 171 | + } | |
| 172 | + else if (selectionliststr == "") | |
| 173 | + { | |
| 174 | + result.Result = SelectionResult.None; | |
| 175 | + result.SelectedKeyList = null; | |
| 176 | + return result; | |
| 177 | + } | |
| 178 | + else if (selectionMode == SelectionMode.Multi && selectionliststr == "*") | |
| 179 | + { | |
| 180 | + selectionKeyList = new List<string>(); | |
| 181 | + selectionParList = new List<object>(); | |
| 182 | + var i = 1; | |
| 183 | + foreach (var mi in MenuItemList) | |
| 184 | + { | |
| 185 | + selectionKeyList.Add(mi.Key); | |
| 186 | + selectionParList.Add(mi.Parameters); | |
| 187 | + } | |
| 188 | + result.Result = SelectionResult.Ok; | |
| 189 | + result.SelectedKeyList = selectionKeyList; | |
| 190 | + result.SelectedParameterList= selectionParList; | |
| 191 | + return result; | |
| 192 | + } | |
| 193 | + selectionKeyList = new List<string>(); | |
| 194 | + selectionParList = new List<object>(); | |
| 195 | + foreach (var selection in selectionliststr.Split(',').ToList()) | |
| 196 | + { | |
| 197 | + string _selection = selection; | |
| 198 | + object _parameters=null; | |
| 199 | + if (!MenuKeyList.Contains(_selection)) | |
| 200 | + { | |
| 201 | + if (!int.TryParse(_selection, out int indexselection) || indexselection < 1 || indexselection > MenuItemList.Count()) | |
| 202 | + { | |
| 203 | + IncorrectSelection($"Selected item {_selection} is not valid!"); | |
| 204 | + result.Result = SelectionResult.Error; | |
| 205 | + result.SelectedKeyList = null; | |
| 206 | + return result; | |
| 207 | + } | |
| 208 | + _selection = GetItemKey(indexselection-1); | |
| 209 | + _parameters = GetItem(indexselection - 1).Parameters; | |
| 210 | + } | |
| 211 | + selectionKeyList.Add(_selection); | |
| 212 | + selectionParList.Add(_parameters); | |
| 213 | + } | |
| 214 | + result.Result = SelectionResult.Ok; | |
| 215 | + result.SelectedKeyList = selectionKeyList; | |
| 216 | + result.SelectedParameterList = selectionParList; | |
| 217 | + return result; | |
| 218 | + } | |
| 219 | + public static void IncorrectSelection(string partxt="") | |
| 220 | + { | |
| 221 | + ColorConsole.WriteLine(); | |
| 222 | + ColorConsole.WriteLine($"Incorrect selection! {partxt} Make a new selection!",ConsoleColor.Red); | |
| 223 | + Console.WriteLine("Press a key to continue..."); | |
| 224 | + Console.ReadKey(); | |
| 225 | + } | |
| 226 | + | |
| 227 | + public void Execute(List<string> selectedkeylist) | |
| 228 | + { | |
| 229 | + object o = null; | |
| 230 | + foreach (var mi in MenuItemList) | |
| 231 | + { | |
| 232 | + if (selectedkeylist.Contains(mi.Key)) | |
| 233 | + { | |
| 234 | + o = mi.Executor(mi.Parameters, o); | |
| 235 | + } | |
| 236 | + } | |
| 237 | + ColorConsole.WriteLine("Press any key to continue...", ConsoleColor.Yellow); Console.ReadKey(); | |
| 238 | + } | |
| 239 | + public MenuItemExecutorFunc GetExecutor(string key) | |
| 240 | + { | |
| 241 | + return MenuItemList.ElementAt(GetItemIx(key)).Executor; | |
| 242 | + } | |
| 243 | + #endregion public tools | |
| 244 | + | |
| 245 | + #region private tools | |
| 246 | + private Menu.Item GetItem(string itemkey) | |
| 247 | + { | |
| 248 | + return MenuItemList.FirstOrDefault(x => x.Key == itemkey); | |
| 249 | + } | |
| 250 | + private Menu.Item GetItem(int ix) | |
| 251 | + { | |
| 252 | + return MenuItemList.ElementAt(ix); | |
| 253 | + } | |
| 254 | + private int GetItemIx(string itemkey) | |
| 255 | + { | |
| 256 | + return MenuKeyList.IndexOf(itemkey); | |
| 257 | + } | |
| 258 | + private string GetItemKey(int ix) | |
| 259 | + { | |
| 260 | + return MenuKeyList.ElementAt(ix); | |
| 261 | + } | |
| 262 | + public void SetParameters(Menu.Selection r, object p=null) | |
| 263 | + { | |
| 264 | + foreach (var mi in this.MenuItemList) | |
| 265 | + { | |
| 266 | + var keyindex = r.SelectedKeyList.IndexOf(mi.Key); | |
| 267 | + if (keyindex != -1) | |
| 268 | + { | |
| 269 | + if (p == null) { mi.Parameters = r.SelectedParameterList.ElementAt(keyindex); } else { mi.Parameters = p; } | |
| 270 | + } | |
| 271 | + } | |
| 272 | + } | |
| 273 | + #endregion private tools | |
| 274 | + public class Item | |
| 275 | + { | |
| 276 | + public Item(string key, string text, MenuItemExecutorFunc executor = null, object parameters = null) | |
| 277 | + { | |
| 278 | + Key = key; | |
| 279 | + Text = text; | |
| 280 | + Executor = executor; | |
| 281 | + Parameters = parameters; | |
| 282 | + } | |
| 283 | + public string Key; | |
| 284 | + public string Text; | |
| 285 | + public MenuItemExecutorFunc Executor; | |
| 286 | + public object Parameters; | |
| 287 | + } | |
| 288 | + } | |
| 289 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Linq; | |
| 4 | +using System.Text; | |
| 5 | +using System.Threading.Tasks; | |
| 6 | + | |
| 7 | +using Microsoft.Web.Administration; | |
| 8 | +using System.Management; | |
| 9 | +using System.Diagnostics; | |
| 10 | + | |
| 11 | +using Vrh.XmlProcessing; | |
| 12 | +using System.Xml.Linq; | |
| 13 | + | |
| 14 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
| 15 | +{ | |
| 16 | + class Program | |
| 17 | + { | |
| 18 | + static void Main(string[] args) | |
| 19 | + { | |
| 20 | + try { Console.SetWindowSize(120, 64); } | |
| 21 | + catch (Exception ex) | |
| 22 | + { | |
| 23 | + ColorConsole.WriteLine("Change the size of the console fonts smaller!"); | |
| 24 | + Console.ReadKey(); | |
| 25 | + return; | |
| 26 | + } | |
| 27 | + | |
| 28 | + var mm = new Menu("Log4ProIS Maintenance Console") | |
| 29 | + .AddMenuItem(new Menu.Item("WAM", "Web Application Manager", WebApplicationManager.Execute)) | |
| 30 | + .AddMenuItem(new Menu.Item("WSM", "Windows Service Manager", WindowsServiceManager.Execute)) | |
| 31 | + .SetSelectionMode(Menu.SelectionMode.Single); | |
| 32 | + | |
| 33 | + mm.ExecuteMenu(); | |
| 34 | + ColorConsole.WriteLine("Press any key to exit..."); Console.ReadKey(); | |
| 35 | + } | |
| 36 | + } | |
| 37 | +} | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs
0 → 100644
| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | +using System.Reflection; | |
| 2 | +using System.Runtime.CompilerServices; | |
| 3 | +using System.Runtime.InteropServices; | |
| 4 | + | |
| 5 | +// General Information about an assembly is controlled through the following | |
| 6 | +// set of attributes. Change these attribute values to modify the information | |
| 7 | +// associated with an assembly. | |
| 8 | +[assembly: AssemblyTitle("Vrh.Log4Pro.MaintenanceConsole")] | |
| 9 | +[assembly: AssemblyDescription("")] | |
| 10 | +[assembly: AssemblyConfiguration("")] | |
| 11 | +[assembly: AssemblyCompany("Microsoft")] | |
| 12 | +[assembly: AssemblyProduct("Vrh.Log4Pro.MaintenanceConsole")] | |
| 13 | +[assembly: AssemblyCopyright("Copyright © Microsoft 2020")] | |
| 14 | +[assembly: AssemblyTrademark("")] | |
| 15 | +[assembly: AssemblyCulture("")] | |
| 16 | + | |
| 17 | +// Setting ComVisible to false makes the types in this assembly not visible | |
| 18 | +// to COM components. If you need to access a type in this assembly from | |
| 19 | +// COM, set the ComVisible attribute to true on that type. | |
| 20 | +[assembly: ComVisible(false)] | |
| 21 | + | |
| 22 | +// The following GUID is for the ID of the typelib if this project is exposed to COM | |
| 23 | +[assembly: Guid("2af86207-84e8-479f-a466-ca65c606b009")] | |
| 24 | + | |
| 25 | +// Version information for an assembly consists of the following four values: | |
| 26 | +// | |
| 27 | +// Major Version | |
| 28 | +// Minor Version | |
| 29 | +// Build Number | |
| 30 | +// Revision | |
| 31 | +// | |
| 32 | +// You can specify all the values or you can default the Build and Revision Numbers | |
| 33 | +// by using the '*' as shown below: | |
| 34 | +// [assembly: AssemblyVersion("1.0.*")] | |
| 35 | +[assembly: AssemblyVersion("1.0.0.0")] | |
| 36 | +[assembly: AssemblyFileVersion("1.0.0.0")] | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Vrh.Log4Pro.MaintenanceConsole.csproj
0 → 100644
| ... | ... | @@ -0,0 +1,167 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
| 3 | + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |
| 4 | + <PropertyGroup> | |
| 5 | + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |
| 6 | + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |
| 7 | + <ProjectGuid>{2AF86207-84E8-479F-A466-CA65C606B009}</ProjectGuid> | |
| 8 | + <OutputType>Exe</OutputType> | |
| 9 | + <RootNamespace>Vrh.Log4Pro.MaintenanceConsole</RootNamespace> | |
| 10 | + <AssemblyName>Vrh.Log4Pro.MaintenanceConsole</AssemblyName> | |
| 11 | + <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> | |
| 12 | + <FileAlignment>512</FileAlignment> | |
| 13 | + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | |
| 14 | + <Deterministic>true</Deterministic> | |
| 15 | + </PropertyGroup> | |
| 16 | + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |
| 17 | + <PlatformTarget>AnyCPU</PlatformTarget> | |
| 18 | + <DebugSymbols>true</DebugSymbols> | |
| 19 | + <DebugType>full</DebugType> | |
| 20 | + <Optimize>false</Optimize> | |
| 21 | + <OutputPath>bin\Debug\</OutputPath> | |
| 22 | + <DefineConstants>DEBUG;TRACE</DefineConstants> | |
| 23 | + <ErrorReport>prompt</ErrorReport> | |
| 24 | + <WarningLevel>4</WarningLevel> | |
| 25 | + </PropertyGroup> | |
| 26 | + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |
| 27 | + <PlatformTarget>AnyCPU</PlatformTarget> | |
| 28 | + <DebugType>pdbonly</DebugType> | |
| 29 | + <Optimize>true</Optimize> | |
| 30 | + <OutputPath>bin\Release\</OutputPath> | |
| 31 | + <DefineConstants>TRACE</DefineConstants> | |
| 32 | + <ErrorReport>prompt</ErrorReport> | |
| 33 | + <WarningLevel>4</WarningLevel> | |
| 34 | + </PropertyGroup> | |
| 35 | + <ItemGroup> | |
| 36 | + <Reference Include="Microsoft.Web.Administration, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> | |
| 37 | + <HintPath>..\packages\Microsoft.Web.Administration.11.1.0\lib\netstandard1.5\Microsoft.Web.Administration.dll</HintPath> | |
| 38 | + </Reference> | |
| 39 | + <Reference Include="Microsoft.Win32.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 40 | + <HintPath>..\packages\Microsoft.Win32.Primitives.4.0.1\lib\net46\Microsoft.Win32.Primitives.dll</HintPath> | |
| 41 | + </Reference> | |
| 42 | + <Reference Include="Microsoft.Win32.Registry, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 43 | + <HintPath>..\packages\Microsoft.Win32.Registry.4.0.0\lib\net46\Microsoft.Win32.Registry.dll</HintPath> | |
| 44 | + </Reference> | |
| 45 | + <Reference Include="System" /> | |
| 46 | + <Reference Include="System.AppContext, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 47 | + <HintPath>..\packages\System.AppContext.4.1.0\lib\net46\System.AppContext.dll</HintPath> | |
| 48 | + </Reference> | |
| 49 | + <Reference Include="System.ComponentModel.Composition" /> | |
| 50 | + <Reference Include="System.Configuration.Install" /> | |
| 51 | + <Reference Include="System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 52 | + <HintPath>..\packages\System.Console.4.0.0\lib\net46\System.Console.dll</HintPath> | |
| 53 | + </Reference> | |
| 54 | + <Reference Include="System.Core" /> | |
| 55 | + <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |
| 56 | + <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath> | |
| 57 | + </Reference> | |
| 58 | + <Reference Include="System.Diagnostics.TraceSource, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 59 | + <HintPath>..\packages\System.Diagnostics.TraceSource.4.0.0\lib\net46\System.Diagnostics.TraceSource.dll</HintPath> | |
| 60 | + </Reference> | |
| 61 | + <Reference Include="System.Diagnostics.Tracing, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 62 | + <HintPath>..\packages\System.Diagnostics.Tracing.4.1.0\lib\net462\System.Diagnostics.Tracing.dll</HintPath> | |
| 63 | + </Reference> | |
| 64 | + <Reference Include="System.Globalization.Calendars, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 65 | + <HintPath>..\packages\System.Globalization.Calendars.4.0.1\lib\net46\System.Globalization.Calendars.dll</HintPath> | |
| 66 | + </Reference> | |
| 67 | + <Reference Include="System.IO, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 68 | + <HintPath>..\packages\System.IO.4.1.0\lib\net462\System.IO.dll</HintPath> | |
| 69 | + </Reference> | |
| 70 | + <Reference Include="System.IO.Compression, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> | |
| 71 | + <HintPath>..\packages\System.IO.Compression.4.1.0\lib\net46\System.IO.Compression.dll</HintPath> | |
| 72 | + </Reference> | |
| 73 | + <Reference Include="System.IO.Compression.FileSystem" /> | |
| 74 | + <Reference Include="System.IO.Compression.ZipFile, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"> | |
| 75 | + <HintPath>..\packages\System.IO.Compression.ZipFile.4.0.1\lib\net46\System.IO.Compression.ZipFile.dll</HintPath> | |
| 76 | + </Reference> | |
| 77 | + <Reference Include="System.IO.FileSystem, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 78 | + <HintPath>..\packages\System.IO.FileSystem.4.0.1\lib\net46\System.IO.FileSystem.dll</HintPath> | |
| 79 | + </Reference> | |
| 80 | + <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 81 | + <HintPath>..\packages\System.IO.FileSystem.Primitives.4.0.1\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath> | |
| 82 | + </Reference> | |
| 83 | + <Reference Include="System.Management" /> | |
| 84 | + <Reference Include="System.Net.Http, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 85 | + <HintPath>..\packages\System.Net.Http.4.1.0\lib\net46\System.Net.Http.dll</HintPath> | |
| 86 | + </Reference> | |
| 87 | + <Reference Include="System.Net.Sockets, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 88 | + <HintPath>..\packages\System.Net.Sockets.4.1.0\lib\net46\System.Net.Sockets.dll</HintPath> | |
| 89 | + </Reference> | |
| 90 | + <Reference Include="System.Numerics" /> | |
| 91 | + <Reference Include="System.Reflection, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 92 | + <HintPath>..\packages\System.Reflection.4.1.0\lib\net462\System.Reflection.dll</HintPath> | |
| 93 | + </Reference> | |
| 94 | + <Reference Include="System.Reflection.TypeExtensions, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 95 | + <HintPath>..\packages\System.Reflection.TypeExtensions.4.4.0\lib\net461\System.Reflection.TypeExtensions.dll</HintPath> | |
| 96 | + </Reference> | |
| 97 | + <Reference Include="System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 98 | + <HintPath>..\packages\System.Runtime.4.1.0\lib\net462\System.Runtime.dll</HintPath> | |
| 99 | + </Reference> | |
| 100 | + <Reference Include="System.Runtime.Extensions, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 101 | + <HintPath>..\packages\System.Runtime.Extensions.4.1.0\lib\net462\System.Runtime.Extensions.dll</HintPath> | |
| 102 | + </Reference> | |
| 103 | + <Reference Include="System.Runtime.InteropServices, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 104 | + <HintPath>..\packages\System.Runtime.InteropServices.4.1.0\lib\net462\System.Runtime.InteropServices.dll</HintPath> | |
| 105 | + </Reference> | |
| 106 | + <Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 107 | + <HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.0.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath> | |
| 108 | + </Reference> | |
| 109 | + <Reference Include="System.Security.Claims, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 110 | + <HintPath>..\packages\System.Security.Claims.4.0.1\lib\net46\System.Security.Claims.dll</HintPath> | |
| 111 | + </Reference> | |
| 112 | + <Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 113 | + <HintPath>..\packages\System.Security.Cryptography.Algorithms.4.2.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath> | |
| 114 | + </Reference> | |
| 115 | + <Reference Include="System.Security.Cryptography.Encoding, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 116 | + <HintPath>..\packages\System.Security.Cryptography.Encoding.4.0.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath> | |
| 117 | + </Reference> | |
| 118 | + <Reference Include="System.Security.Cryptography.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 119 | + <HintPath>..\packages\System.Security.Cryptography.Primitives.4.0.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath> | |
| 120 | + </Reference> | |
| 121 | + <Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 122 | + <HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.1.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath> | |
| 123 | + </Reference> | |
| 124 | + <Reference Include="System.Security.Principal.Windows, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 125 | + <HintPath>..\packages\System.Security.Principal.Windows.4.0.0\lib\net46\System.Security.Principal.Windows.dll</HintPath> | |
| 126 | + </Reference> | |
| 127 | + <Reference Include="System.ServiceProcess" /> | |
| 128 | + <Reference Include="System.ServiceProcess.ServiceController, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |
| 129 | + <HintPath>..\packages\System.ServiceProcess.ServiceController.4.1.0\lib\net461\System.ServiceProcess.ServiceController.dll</HintPath> | |
| 130 | + </Reference> | |
| 131 | + <Reference Include="System.Web" /> | |
| 132 | + <Reference Include="System.Web.ApplicationServices" /> | |
| 133 | + <Reference Include="System.Xml.Linq" /> | |
| 134 | + <Reference Include="System.Data.DataSetExtensions" /> | |
| 135 | + <Reference Include="Microsoft.CSharp" /> | |
| 136 | + <Reference Include="System.Data" /> | |
| 137 | + <Reference Include="System.Xml" /> | |
| 138 | + <Reference Include="Vrh.XmlProcessing, Version=1.23.0.0, Culture=neutral, processorArchitecture=MSIL"> | |
| 139 | + <HintPath>..\packages\Vrh.XmlProcessing.1.23.0\lib\net45\Vrh.XmlProcessing.dll</HintPath> | |
| 140 | + </Reference> | |
| 141 | + </ItemGroup> | |
| 142 | + <ItemGroup> | |
| 143 | + <Compile Include="ConsoleFunction - CommandLineParser.cs" /> | |
| 144 | + <Compile Include="ConsoleFunction - ColorConsole.cs" /> | |
| 145 | + <Compile Include="ConsoleFunction - Menu.cs" /> | |
| 146 | + <Compile Include="WindowsServiceManager.cs" /> | |
| 147 | + <Compile Include="WebApplicationManager.cs" /> | |
| 148 | + <Compile Include="Program.cs" /> | |
| 149 | + <Compile Include="Properties\AssemblyInfo.cs" /> | |
| 150 | + </ItemGroup> | |
| 151 | + <ItemGroup> | |
| 152 | + <None Include="App.config"> | |
| 153 | + <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |
| 154 | + </None> | |
| 155 | + <None Include="packages.config" /> | |
| 156 | + <None Include="Vrh.NugetModuls.Documentations\Vrh.XmlProcessing\ReadMe.md" /> | |
| 157 | + </ItemGroup> | |
| 158 | + <ItemGroup> | |
| 159 | + <Content Include="Config.xml"> | |
| 160 | + <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |
| 161 | + </Content> | |
| 162 | + <Content Include="XmlParser.xml"> | |
| 163 | + <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |
| 164 | + </Content> | |
| 165 | + </ItemGroup> | |
| 166 | + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |
| 167 | +</Project> | |
| 0 | 168 | \ No newline at end of file | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/Vrh.NugetModuls.Documentations/Vrh.XmlProcessing/ReadMe.md
0 → 100644
| ... | ... | @@ -0,0 +1,958 @@ |
| 1 | +# Vrh.XmlProcessing | |
| 2 | +VRH-s XML paraméter fájlok feldolgozását támogató komponens. | |
| 3 | +Hasznos függvényekkel, osztályokkal és rendszeresen előforduló szerkezetek leképezésével. | |
| 4 | + | |
| 5 | +> Fejlesztve és tesztelve **4.5** .NET framework alatt. | |
| 6 | +> Teljes funkcionalitás és hatékonyság kihasználásához szükséges legalacsonyabb framework verzió: **4.5** | |
| 7 | + | |
| 8 | +## Főbb összetevők | |
| 9 | + > * [XmlLinqBase osztály](##XmlLinqBase-osztaly) Xml feldogozásokhoz készülő osztályok absztrakt alaposztálya. | |
| 10 | + > * [VariableDictionary](##VariableDictionary) Behelyettesítendő változók összegyűjtése és a behelyettesítés végrehajtása. | |
| 11 | + > * [XmlCondition osztály](##XmlCondition-osztaly) A ```<Condition>``` elem feldogozását segítő osztály. | |
| 12 | + > * [XmlVariable osztály](##XmlVariable-osztaly) Az ```<XmlVar>``` vagy bármely Name, LCID attribútummal és értékkel rendelkező elem feldogozását segítő osztály. | |
| 13 | + > * [XmlConnection osztály](##XmlConnection-osztaly) XmlParser kapcsolati string feldogozása és kifejtése. | |
| 14 | + > * [XmlParser osztály](##XmlParser-osztaly) Az ```<XmlParser>``` elem feldogozását elvégző osztály. | |
| 15 | + | |
| 16 | + > * [ConnectionStringStore osztály](##ConnectionStringStore-osztaly) Kapcsolati sztringeket szolgáltató static osztály. | |
| 17 | + | |
| 18 | +## XmlLinqBase osztály | |
| 19 | +Egy absztrakt alaposztály, mely minden specialitás nélkül alkalmas egy XML állomány | |
| 20 | +elemeinek és attribútumainak beolvasására és a típusos értékek előállítására. Az osztály | |
| 21 | +a System.Xml.Linq névtér beli xml kezeléshez nyújt segédeszközöket. Az osztályban minden | |
| 22 | +tulajdonság és metódus protected hatáskörű. | |
| 23 | + | |
| 24 | +Felhasználási minta: | |
| 25 | +```javascript | |
| 26 | +public class MyClass : XmlLinqBase { ... } | |
| 27 | +``` | |
| 28 | + | |
| 29 | +Tulajdonságok|Leírás | |
| 30 | +:----|:---- | |
| 31 | +CurrentFileName|A Load metódus által legutóbb sikeresen betöltött xml fájl neve. Csak olvasható. Értéke akkor íródik felül, ha a Load minden tekintetben sikeres. | |
| 32 | +RootElement|GetXElement metódusban megadott útvonal ettől az elemtől számítódik. A Load metódus beállítja (felülírja) ezt az elemet. | |
| 33 | +EnableTrim|A GetValue metódusok számára engedélyezi a whitespace karakterek eltávolítását a megtalált érték elejéről és végéről. Alapértelmezett értéke: true. | |
| 34 | + | |
| 35 | +Metódusok|Leírás | |
| 36 | +:----|:---- | |
| 37 | +```void Load(string xmlFileName)```|A megadott fájlból betölti az XML struktúrát. Beállítja a CurrentFileName tulajdonságot. | |
| 38 | +```XElement GetXElement(params string[] elementPath)```|A RootElement-ben lévő elemtől a sorban megadott elemeken keresztül elérhető elemet adja vissza. | |
| 39 | +```XElement GetXElement(XElement root, params string[] elementPath)```|A root parméterben megadott elemtől a sorban megadott elemeken keresztül elérhető elemet adja vissza. | |
| 40 | +```XElement GetXElement(string elementPath, char separator = '/')```|A RootElement-ben lévő elemtől az elementhPath paraméterben megadott útvonalon keresztül elérhető elemet adja vissza. | |
| 41 | +```XElement GetXElement(string elementPath, bool isRequired, char separator = '/')```|Mint az előző, de az elem hiánya esetén és isRequired igaz értéke esetén hibát dob. | |
| 42 | +```XElement GetXElement(XElement root, string elementPath, char separator = '/')```|A root paraméterben megadott elemtől az elementhPath paraméterben megadott útvonalon keresztül elérhető elemet adja vissza. | |
| 43 | +```XElement GetXElement(XElement root, string elementPath, bool isRequired, char separator = '/')```|Mint az előző, de az elem hiánya esetén és isRequired igaz értéke esetén hibát dob. | |
| 44 | +```T GetValue<T>(XElement xelement, T defaultValue, bool isThrowException = false, bool isRequired = false)```|Visszad egy element értéket a defaultValue típusának megfelelően. | |
| 45 | +```T GetValue<T>(string attributeName, XElement xelement, T defaultValue, bool isThrowException = false, bool isRequired = false)```|Visszadja az xelement elem alatti, megnevezett attribútum értékét. | |
| 46 | +```T GetValue<T>(System.Xml.Linq.XAttribute xattribute, T defaultValue, bool isThrowException = false, bool isRequired = false)```|Visszadja az attribútum értékét a kért típusban. | |
| 47 | +```T GetValue<T>(string stringValue, T defultValue)```|A megadott típusra konvertál egy stringet, ha a konverzió lehetséges. | |
| 48 | +```TEnum GetEnumValue<TEnum>(XAttribute xattribute, TEnum defaultValue, bool ignoreCase = true)```|Attribútum értéket enum típus értékké konvertálja. | |
| 49 | +```TEnum GetEnumValue<TEnum>(XElement xelement, TEnum defaultValue, bool ignoreCase = true)```|Elem értéket enum típus értékké konvertálja. | |
| 50 | +```string GetXmlPath(XAttribute xattribute)```|Xattribute útvonala '/Element0/Element1/Element2.Attribute' formában. | |
| 51 | +```string GetXmlPath(XElement xelement)```|XElement útvonala 'Element0/Element1/Element2' formában. | |
| 52 | +```void ThrowEx(string mess, params object[] args)```|System.ApplicationException dobása a megadott formázott üzenettel. | |
| 53 | + | |
| 54 | +### Beépített kiterjeszthető osztályok | |
| 55 | + | |
| 56 | +#### XmlLinqBase.ElementNames osztály | |
| 57 | +Általában használatos elemnevek kiterjeszthető osztálya. | |
| 58 | + | |
| 59 | +Állandó|Értéke|Leírás | |
| 60 | +:----|:----|:---- | |
| 61 | +VALUE|"Value"|XML tagokban lehetséges 'Value' elem eléréséhez hasznos állandó. | |
| 62 | + | |
| 63 | +#### XmlLinqBase.Messages osztály | |
| 64 | +Általában használatos üzenetek kiterjeszthető osztálya. | |
| 65 | + | |
| 66 | +Állandó|Értéke|Leírás | |
| 67 | +:----|:----|:---- | |
| 68 | +ERR_FILENOTEXIST|"File does not exist! File = {0}"|Nem létező fájl üzenete 1 behelyttesítéssel. | |
| 69 | +ERR_XMLROOT|"The root element is missing or corrupt! File = {0}"|'Root' elem hiányzik vagy hibás XML üzenet 1 behelyettesítéssel. | |
| 70 | +ERR_MISSINGELEMENT|"The '{0}' element is missing !"|Az elem hiányzik üzenet 1 behelyettesítéssel. | |
| 71 | +ERR_MISSINGATTRIBUTE|"The '{0}' attribute is missing in the '{1}' element!"|Az attribútum hiányzik üzenet 2 behelyettesítéssel. | |
| 72 | +ERR_REQUIREDELEMENT|"Value of the '{0}' element is null or empty!"|Szükséges elem null vagy üres üzenet 1 behelyettesítéssel. | |
| 73 | +ERR_REQUIREDATTRIBUTE|"Value of the '{0}' attribute is null or empty in the '{1}' element!"|Szükséges attribútum null vagy üres üzenet 2 behelyettesítéssel. | |
| 74 | +ERR_PARSETOTYPE|"The '{0}' string is not {1} type! Place='{2}'"|Típus konvertálása sikertelen üzenet 3 behelyettesítéssel. | |
| 75 | + | |
| 76 | + | |
| 77 | +## VariableDictionary | |
| 78 | +Egy ```System.Collections.Generic.Dictionary<string,string>``` alapú osztály, mely kiterjesztésre került abból a célból, hogy alkalmas legyen Név és Érték | |
| 79 | +kulcspárok tárolására, és azok behelyettesítésére egy megadott cél szövegben. Az osztály létrehozható úgy , hogy tartalmazza a rendszerváltozókat. | |
| 80 | +A [rendszerváltozók](####A-rendszervaltozok) nevei a ```SystemVariableNames``` statikus osztályban érhetőek el. Ha engedélyezve van, akkor | |
| 81 | +példányosításkor egyből létrejönnek a rendszer változók is a ...BACK változók kivételével, azok ugyanis behelyettesítéskor értékelődnek ki, | |
| 82 | +nem is szerepelnek a szótárban. A ...BACK változók kiértékelése csak akkor következik be behelyettesítéskor, ha a rendszerváltozók engedélyezve vannak. | |
| 83 | +Behelyettesítéskor a változókat az osztály NameSeparator tulajdonság közé illesztve keresi. A NameSeparator tulajdonság | |
| 84 | +alapértelmezett értéke "@@", de átállítható, ha a környezetben más használatos. | |
| 85 | + | |
| 86 | +#### Konstruktorok | |
| 87 | +##### ```new VariableDictionary()``` | |
| 88 | +E konstruktor hatására egy olyan példány jön létre, mely a változónevek tekintetében betűérzékeny, nem tartalmazza a rendszerváltozókat, és az alapértelmezett | |
| 89 | +("@@") névelválasztó állítódik be. | |
| 90 | + | |
| 91 | +##### ```new VariableDictionary(string lcid, string userName)``` | |
| 92 | +E konstruktor hatására egy olyan példány jön létre, mely a változónevek tekintetében betűérzékeny, tartalmazza a rendszerváltozókat, és az alapértelmezett | |
| 93 | +("@@") névelválasztó állítódik be. A két paraméter az LCID és USERNAME rendszerváltozók értékét állítja be. Az ```lcid``` paraméter kötelező, | |
| 94 | +és érvényes nyelvi kódnak kell lennie. | |
| 95 | + | |
| 96 | +##### ```new VariableDictionary(VariableDictionary.Configuration configuration)``` | |
| 97 | +E konstruktor esetén a ```configuration``` paraméterben található tulajdonságok határozzák meg az osztály illetve a konstruktor viselkedését. | |
| 98 | +###### Variable.Configuration osztály | |
| 99 | +Tulajdonság|Típus|Leírás | |
| 100 | +:----|:----|:---- | |
| 101 | +IsCaseSensitive|```bool```|Ha true, akkor a kis és nagy betűk különbözőnek számítanak a változóneveknél. Alapértelmezett érték: true. | |
| 102 | +IsIncludeSystemVariables|```bool```|Ha true, akkor a példányosításkor automatikusan létrejönnek a rendszerváltozók. Alapértelmezett érték: false. | |
| 103 | +LCID|```string```|Ha ebben az osztályban az <c>IsIncludeSystemVariables</c> értéke igaz, akkor ez az érték inicializálja az "LCID" rendszerváltozót. Alapértelmezett érték: null. | |
| 104 | +NameSeparator|```string```|A változónevek elválasztó jelei, mely felülírja az alapértelmezett "@@" értéket. Alapértelmezett értéke: "@@" | |
| 105 | +UserName|```string```|Ha ebben az osztályban az <c>IsIncludeSystemVariables</c> értéke igaz, akkor ez az érték inicializálja a "USERNAME" rendszerváltozót. | |
| 106 | + | |
| 107 | +Ha a rendszer változók létrehozása engedélyezett, akkor az LCID értékének érvényes nyelvi kódnak kell lennie, egyébként hiba keletkezik. | |
| 108 | + | |
| 109 | +#### Tulajdonságok és metódusok | |
| 110 | + | |
| 111 | +> A táblázatokban csak a ```System.Collections.Generic.Dictionary<string,string>``` | |
| 112 | +osztályt kiterjesztő elemeket mutatjuk be. | |
| 113 | + | |
| 114 | +Tulajdonságok|Leírás | |
| 115 | +:----|:---- | |
| 116 | +CurentCultureInfo|Az LCID változó beállításakor kap értéket. Csak olvasható. | |
| 117 | +NameSeparator|A változó neveket e separátorok közé illesztve keresi a szövegben. | |
| 118 | +IsCaseSensitive|A változónevek kis/nagybetű érzékenyek, vagy sem.Csak konstruktoron keresztül állítható, egyébként olvasható. | |
| 119 | +IncludeSystemVariables|Felismeri-e a rendszer változók neveit, vagy sem.Csak konstruktoron keresztül állítható, egyébként olvasható. | |
| 120 | + | |
| 121 | +Ha a NameSeparator hossza 1, akkor a változót keretező kezdő és befejező karakter azonos, egyébként a | |
| 122 | +2. karakter lesz a befejező jel. Alapértelmezett értéke "@@". Amennyiben szükség van egy alternatív | |
| 123 | +elválasztó párra, akkor párosával növelhető az elválasztó párok száma. Példa: "@@##". | |
| 124 | +Ilyenkor elsőként a "@" jelek közé zárt neveket keres, ha ilyet nem talál, akkor kísérletet tesz a "#" | |
| 125 | +jelek közé zárt változó név keresésre. Ha a Name separator nem 1, 2 vagy páros hoszzúságú, akkor hiba | |
| 126 | +keletkezik. | |
| 127 | + | |
| 128 | +Metódusok|Leírás | |
| 129 | +:----|:---- | |
| 130 | +```void Add(string name, string value)```|Egy darab név-érték pár hozzáadása a gyűjteményhez. | |
| 131 | +```void Add((NameValueCollection collection, bool isOverwrite = false)```|Név-érték párok hozzáadása egy létező ```NameValueCollection```-ból. Ha ```isOverwrite``` igaz, akkor az azonos kulcs értékű elemet felülírja. | |
| 132 | +```void Add((Dictionary<string,string> dictionary, bool isOverwrite = false)```|Név-érték párok hozzáadása egy létező ```Dictionary<string,string>```-ból. Ha ```isOverwrite``` igaz, akkor az azonos kulcs értékű elemet felülírja. | |
| 133 | +```void Set(string name, string value)```|Megadott nevű változó értékének módosítása. | |
| 134 | +```bool ContainsVariable(string name)```|Igaz értékkel jelzi, ha a név már szerepel a gyűjteményben. | |
| 135 | +```bool IsValidName(string name)```|Változónév ellenőrzése. A névnek meg kell felelnie az "[a-zA-Z_]\w*" reguláris kifejezésnek. | |
| 136 | +```void ResetSystemVariables()```|Rendszerváltozók értékének (újra)beállítása az LCID változó kivételével. | |
| 137 | +```string Substitution(string text)```|A szövegbe behelyettesíti a gyűjteményben található változók értékét. | |
| 138 | +```string Substitution(string text, string name)```|A szövegbe behelyettesíti a gyűjteményben a ```name``` változó értékét. | |
| 139 | +```public List<string> FindVariables(string text)```|A függvény megnézi, hogy a megadott <paramref name="text"/> paraméterben léteznek-e a gyűjteményben szereplő változók. A megtalált elemek kulcsaival egy listát képez. | |
| 140 | + | |
| 141 | +#### A rendszerváltozók | |
| 142 | +A rendszerváltozók neve egy statikus SystemVariableNames nevű osztályban érhetőek el. | |
| 143 | +> Az XML fájban való hivatkozás bemutatásánál az alapértelmezett név elválasztót használtuk. | |
| 144 | + | |
| 145 | +Név|XML hivatkozás|Leírás | |
| 146 | +:----|:----|:------ | |
| 147 | +LCID|@LCID@|A nyelvi kódot tartalmazó rendszer változó neve. | |
| 148 | +USERNAME|@USERNAME@|Egy felhasználó név, melyet példányosításkor vagy később is be lehet állítani. | |
| 149 | +TODAY|@TODAY@|Mai nap rendszer változó neve. | |
| 150 | +YESTERDAY|@YESTERDAY@|Tegnap rendszer változó neve. | |
| 151 | +NOW|@NOW@|Most rendszerváltozó neve. | |
| 152 | +THISWEEKMONDAY|@THISWEEKMONDAY@|E hét hétfő rendszer változó neve. | |
| 153 | +THISWEEKFRIDAY|@THISWEEKFRIDAY@|E hét péntek rendszer változó neve. | |
| 154 | +LASTWEEKMONDAY|@LASTWEEKMONDAY@|Múlt hét hétfő rendszer változó neve. | |
| 155 | +LASTWEEKFRIDAY|@LASTWEEKFRIDAY@|Múlt hét péntek rendszer változó neve | |
| 156 | +THISMONTH1STDAY|@THISMONTH1STDAY@|E hónap első napja rendszer változó neve. | |
| 157 | +THISMONTHLASTDAY|@THISMONTHLASTDAY@|E hónap utolsó napja rendszer változó neve. | |
| 158 | +LASTMONTH1STDAY|@LASTMONTH1STDAY@|Múlt hónap első napja rendszer változó neve. | |
| 159 | +LASTMONTHLASTDAY|@LASTMONTHLASTDAY@|Múlt hónap utolsó napja rendszer változó neve. | |
| 160 | +MINUTESBACK|@MINUTESBACK#@|Valahány(#) perccel korábbi időpont. | |
| 161 | +HOURSBACK|@HOURSBACK#@|Valahány(#) órával korábbi időpont. | |
| 162 | +DAYSBACK|@DAYSBACK#@|Valahány(#) nappal korábbi nap. | |
| 163 | +WEEKSBACK|@WEEKSBACK#@|Valahány(#) héttel (1hét=7nap) korábbi nap. | |
| 164 | +MONTHSBACK|@MONTHSBACK#@|Valahány(#) hónappal korábbi nap. | |
| 165 | + | |
| 166 | +A MINUTESBACK, a HOURSBACK és a NOW formátuma "ÉÉÉÉHHNNÓÓPPMM", míg a többi dátum típusú változónak "ÉÉÉÉHHNN". | |
| 167 | + | |
| 168 | +Rövidítés|jelentése | |
| 169 | +:----|:---- | |
| 170 | +É| év száma 4 számjeggyel | |
| 171 | +H| a hónap száma 2 számjegyen vezető zéróval | |
| 172 | +N| a nap száma 2 számjegyen vezető zéróval | |
| 173 | +Ó| az óra 2 számjegyen vezető zéróval | |
| 174 | +P| a perc 2 számjegyen vezető zéróval | |
| 175 | +M| a másodperc 2 számjegyen vezető zéróval | |
| 176 | + | |
| 177 | + | |
| 178 | +#### Osztály használatára egy minta | |
| 179 | +```javascript | |
| 180 | +/// <summary> | |
| 181 | +/// Minta a VariableDictionary osztály használatára. | |
| 182 | +/// </summary> | |
| 183 | +private static void VariableDictionaryTest() | |
| 184 | +{ | |
| 185 | + try | |
| 186 | + { | |
| 187 | + // Az osztály példányosítása. Nyelvi kód paraméter kötelező. | |
| 188 | + VariableDictionary vd = new VariableDictionary("hu-HU", User.Identity.Name); | |
| 189 | + Show(vd); | |
| 190 | + | |
| 191 | + System.Threading.Thread.Sleep(1000); | |
| 192 | + | |
| 193 | + vd.ResetSystemVariables(); //rendszerváltozók újra beállítása | |
| 194 | + Show(vd); | |
| 195 | + | |
| 196 | + vd.Add("VLTZ", "vltz értéke"); //egy változó hozzáadása | |
| 197 | + vd["TODAY"] = "ma"; //egy változó módosítása | |
| 198 | + vd.Remove("NOW"); //egy változó törlése | |
| 199 | + Show(vd); | |
| 200 | + | |
| 201 | + string text = String.Concat( | |
| 202 | + "aaaaa@YESTERDAY@bbbbbbb@TODAY@cccccccc", | |
| 203 | + "@LASTMONTHLASTDAY@ddddddddddd\neee@DAYSBACK3@ff", | |
| 204 | + "ff@WEEKSBACK4@gggg@MONTHSBACK10@hhhh" | |
| 205 | + ); | |
| 206 | + string result = vd.Substitution(text); //szövegben lévő hivatkozások behelyettesítése | |
| 207 | + Console.WriteLine(); | |
| 208 | + Console.WriteLine($"text= {result}"); | |
| 209 | + } | |
| 210 | + catch (Exception ex) | |
| 211 | + { | |
| 212 | + Console.WriteLine(ex.Message); | |
| 213 | + } | |
| 214 | +} | |
| 215 | + | |
| 216 | +private static void Show(VariableDictionary vd) | |
| 217 | +{ | |
| 218 | + Console.WriteLine(); | |
| 219 | + foreach (KeyValuePair<string,string> s in vd) | |
| 220 | + Console.WriteLine($"Name: {s.Key,-25}Value: {s.Value}"); | |
| 221 | +} | |
| 222 | +``` | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | +## XmlCondition osztály | |
| 227 | +Az alábbi xml struktúra feldolgozását segítő osztály: | |
| 228 | +```xml | |
| 229 | +<Condition Type="equal" Test="@VAR1@" With="one"> | |
| 230 | + four | |
| 231 | + <Conditions> | |
| 232 | + <Condition Type="equal" Test="@VAR1@" With="xxx">xxx</Condition> | |
| 233 | + <Condition Type="equal" Test="@VAR1@" With="one">five</Condition> | |
| 234 | + </Conditions> | |
| 235 | +</Condition> | |
| 236 | +``` | |
| 237 | +A 'Condition' XML elem megszerzése után egy példányosítással előáll egy XmlCondition | |
| 238 | +típus. | |
| 239 | +```javascript | |
| 240 | +XmlCondition condition = new XmlCondition(XML.Element("Condition")); | |
| 241 | +``` | |
| 242 | +Tulajdonság|Típus|Leírás | |
| 243 | +:----|:----|:---- | |
| 244 | +Type|```string```|A feltétel típusa. Types enum értékek valamelyike. Alapértelmezett érték: Types.Equal. | |
| 245 | +Test|```string```|A egyik tesztelendő karakterlánc. Lehet benne XML változó. Types.Match esetén a kiértékelendő karakterléncot tartalmazza. | |
| 246 | +With|```string```|A másik tesztelendő karakterlánc. Lehet benne XML változó. Types.Match esetén a kiértékelő reguláris kifejezést tartalmazza. | |
| 247 | +Value|```string```|Igaz értékű feltétel esetén, ez lesz a releváns érték. | |
| 248 | +Conditions|```List<XmlCondition>```|XmlCondition típusú elemek listája. Ha a releváns érték más feltétel(ek)től is függ. | |
| 249 | + | |
| 250 | +Metódus|Leírás | |
| 251 | +:----|:---- | |
| 252 | +bool Evaluation(VariableDictionary xmlVars)|A feltétel kiértékelése. Mivel létezhetnek hivatkozások, ezért meg kell adni a változók gyűjteményét. | |
| 253 | + | |
| 254 | +### XmlCondition.Types enum | |
| 255 | +A feltételekben a "Type" attribútumban megadható típusok. | |
| 256 | + | |
| 257 | +Név|Leírás | |
| 258 | +:----|:---- | |
| 259 | +```XmlCondition.Types.Else```|Mindig igaz feltétel típus. | |
| 260 | +```XmlCondition.Types.Equal```|Egyenlő. Ez az alapértelmezés. | |
| 261 | +```XmlCondition.Types.NotEqual```|Nem egyenlő. | |
| 262 | +```XmlCondition.Types.Match```|Regex kifejezés. | |
| 263 | + | |
| 264 | +### Beépített kiterjeszthető osztályok | |
| 265 | + | |
| 266 | +#### XmlCondition.ElementNames osztály | |
| 267 | +Általában használatos elemnevek kiterjeszthető osztálya. | |
| 268 | + | |
| 269 | +Állandó|Értéke|Leírás | |
| 270 | +:----|:----|:---- | |
| 271 | +CONDITIONS|"Conditions"|XML tagokban lehetséges 'Conditions' elem eléréséhez hasznos állandó. | |
| 272 | +CONDITION|"Condition"|XML tagokban lehetséges 'Condition' elem eléréséhez hasznos állandó. | |
| 273 | + | |
| 274 | +#### XmlCondition.AttributeNames osztály | |
| 275 | +Általában használatos attribútumnevek kiterjeszthető osztálya. | |
| 276 | + | |
| 277 | +Állandó|Értéke|Leírás | |
| 278 | +:----|:----|:---- | |
| 279 | +TYPE|"Type"|XML tagokban lehetséges 'Type' attribútum eléréséhez hasznos állandó. | |
| 280 | +TEST|"Test"|XML tagokban lehetséges 'Test' attribútum eléréséhez hasznos állandó. | |
| 281 | +WITH|"With"|XML tagokban lehetséges 'With' attribútum eléréséhez hasznos állandó. | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | +## XmlVariable osztály | |
| 286 | +Az alábbi struktúra feldolgozását segítő osztály: | |
| 287 | +```xml | |
| 288 | +<XmlVar Name="VAR3" LCID="hu-HU"> | |
| 289 | + <Conditions> | |
| 290 | + <Condition Type="equal" Test="@VAR1@" With="one"> | |
| 291 | + four | |
| 292 | + <Conditions> | |
| 293 | + <Condition Type="equal" Test="@VAR1@" With="xxx">xxx</Condition> | |
| 294 | + <Condition Type="equal" Test="@VAR1@" With="one">five</Condition> | |
| 295 | + </Conditions> | |
| 296 | + </Condition> | |
| 297 | + </Conditions> | |
| 298 | + three | |
| 299 | +</XmlVar> | |
| 300 | + | |
| 301 | +VAGY | |
| 302 | + | |
| 303 | +<XmlVar Name="VAR4" LCID="hu-HU">érték</XmlVar> | |
| 304 | +``` | |
| 305 | +Xml változókat leképező osztály. Tulajdonképpen minden elem, melynek 'Name', 'LCID' attribútuma lehetséges, | |
| 306 | +és van 'Value' tulajdonsága, és lehetnek benne feltétek (Conditions). | |
| 307 | +Az 'XmlVar' XML elem megszerzése után egy példányosítással előáll egy XmlVariable típus. | |
| 308 | +```javascript | |
| 309 | +XmlVariable variable = new XmlVariable(XML.Element("XmlVar")); | |
| 310 | +``` | |
| 311 | + | |
| 312 | +Tulajdonság|Típus|Leírás | |
| 313 | +:----|:----|:---- | |
| 314 | +Name|```string```|A változó neve. Csak olyan változó jön létre a példányosításkor, amelynek létezik a megnevezése. | |
| 315 | +LCID|```string```|A változó értékét, melyik nyelvi környezet esetén lehet felhasználni. Ha nincs vagy üres, akkor mindegyikben. | |
| 316 | +Value|```string```| A változó értéke. | |
| 317 | +Conditions|```List<XmlCondition>```|A változó végleges értékét befolyásoló feltételek listája. Az első igaz érték lesz a végleges érték. | |
| 318 | + | |
| 319 | +Metódus|Leírás | |
| 320 | +:----|:---- | |
| 321 | +bool Evaluation(VariableDictionary xmlVars)|A változó kiértékelése. Mivel létezhetnek hivatkozások a feltételekben, ezért meg kell adni a változók gyűjteményét. | |
| 322 | + | |
| 323 | +### Beépített kiterjeszthető osztályok | |
| 324 | + | |
| 325 | +#### XmlVariable.ElementNames osztály | |
| 326 | +Általában használatos elemnevek kiterjeszthető osztálya. Az XmlLinqBase hasonló osztályát terjeszti ki. | |
| 327 | + | |
| 328 | +Állandó|Értéke|Leírás | |
| 329 | +:----|:----|:---- | |
| 330 | +XMLVAR|"XmlVar"|XML tagokban lehetséges 'XmlVar' elem eléréséhez hasznos állandó. | |
| 331 | +CONNECTIONSTRING|"ConnectionString"|XML tagokban lehetséges 'ConnectionString' elem eléréséhez hasznos állandó. | |
| 332 | + | |
| 333 | +#### XmlVariable.AttributeNames osztály | |
| 334 | +Általában használatos attribútumnevek kiterjeszthető osztálya. | |
| 335 | + | |
| 336 | +Állandó|Értéke|Leírás | |
| 337 | +:----|:----|:---- | |
| 338 | +NAME|"Name"|XML tagokban lehetséges 'Name' attribútum eléréséhez hasznos állandó. | |
| 339 | +LCID|"LCID"|XML tagokban lehetséges 'LCID' attribútum eléréséhez hasznos állandó. | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | +## XmlConnection osztály | |
| 344 | +Az XmlPaser példányosításához egy kapcsolati sztring szükséges, amelyet ez az osztály ellenőriz és | |
| 345 | +kifejt. Az alábbi táblázat "Tulajdonság" oszlopában zárójelben az látható, hogy az adott összetevőnek | |
| 346 | +milyen néven kell szerepelnie a kapcsolati stringben. | |
| 347 | + | |
| 348 | +Tulajdonság|Típus|Leírás | |
| 349 | +:----|:----|:---- | |
| 350 | +Root (root)|```string```|A gyökér XML fájl az elérési útvonalával együtt, tartalmazhat relatív útvonalat is. | |
| 351 | +ConfigurationName (config)|```string```|A konfiguráció neve, amit keresünk a gyökér XmlParser fájlban. | |
| 352 | +File (file)|```string```|Ha ez van megadva a connection stringben, akkor itt van a komponens xml paraméter fájlja. | |
| 353 | +Element (element)|```string```|Ha ez van megadva a connection stringben, akkor a komponens xml paraméter fájljában ezen elem alatt található a struktúra. | |
| 354 | + | |
| 355 | +Metódus|Leírás | |
| 356 | +:----|:---- | |
| 357 | +```void SetPath(string appPath)```|A 'Root' és 'File' tulajdonságok relatív értékének feloldása a megadott útvonallal. | |
| 358 | + | |
| 359 | +#### Alapértelmezettől eltérő konstruktorok | |
| 360 | +Konstruktor|Leírás | |
| 361 | +:----|:---- | |
| 362 | +```XmlConnection(string xmlConnectionString, bool isRequired = true)```|XmlConnection példányosítása egy kapcsolati sztring megadásával, melynek során a sztring ellenőrzésre és feldolgozásra kerül. | |
| 363 | +```XmlConnection(string xmlConnectionString, string defaultValue, DefaultTypes defaultType = DefaultTypes.File)```|XmlConnection példányosítása egy kapcsolati sztring megadásával, melynek során a sztring ellenőrzésre és feldolgozásra kerül. Alapértelmezett értéket lehet megadni a "file" vagy "config" elemnek, ha azok üresek egyébként. | |
| 364 | + | |
| 365 | +#### Nyilvános állandók | |
| 366 | +Elérésükre egy minta: | |
| 367 | +```javascript | |
| 368 | +XmlConnection.CSNAME_ROOT | |
| 369 | +``` | |
| 370 | +Állandó|Értéke|Leírás | |
| 371 | +:----|:----|:---- | |
| 372 | +CSNAME_ROOT|"root"|A kapcsolati sztring "root" elem megnevezésének állandója. | |
| 373 | +CSNAME_CONFIG|"config"|A kapcsolati sztring "config" elem megnevezésének állandója. | |
| 374 | +CSNAME_FILE|"file"|A kapcsolati sztring "file" elem megnevezésének állandója. | |
| 375 | +CSNAME_ELEMENT|"element"|A kapcsolati sztring "element" elem megnevezésének állandója. | |
| 376 | +SEPARATOR_NAMEVALUE|"="|Egy elemben a név és értéket elválasztó jel. | |
| 377 | +SEPARATOR_ITEM|";"|A kapcsolati sztringben az egyes elemeket elválasztó jel. | |
| 378 | + | |
| 379 | +#### Kapcsolati sztring felépítése: | |
| 380 | +A minimum igény, hogy a 'config' vagy a 'file' tagnak szerepelnie kell. | |
| 381 | +A config az erősebb, ha mindkettő szerepel. Pár minta: | |
| 382 | +* "root=D:\SandBox\XmlParser\XmlParser.xml;config=FileManager" vagy | |
| 383 | +* "root=D:\SandBox\XmlParser\XmlParser.xml;file=D:\aaa\bbb\FileManager.xml;element=RootAlattiElemNév" | |
| 384 | +* Ha 'root' nem szerepel, akkor a gyökér fájl (1) elsődleges alapértelmezését az alkalmazás appconfig file-jában levő | |
| 385 | +"Vrh.XmlParser:root" nevű elem tartalmazza; ha ez nem létezik, vagy értéke üres, akkor (2) a másodlagos alapértelmezés | |
| 386 | +"~/App_Data/XmlParser/XmlParser.xml". | |
| 387 | +* A felhasználó komponensek fogadhatnak üres kapcsolati stringet, ha számukra | |
| 388 | +van érvényes alapértelmezett konfiguráció név. Például a FileManager meghívható kapcsolati sztring nélkül, | |
| 389 | +akkor a FilManager a következő sztringet generálja: "config:FileManager", és ezzel inicializálja az XmlParser-t. | |
| 390 | + | |
| 391 | + | |
| 392 | +## XmlParser osztály | |
| 393 | +Az 'XmlParser' XML elem feldolgozását elvégző absztrakt osztály. A VRH paraméterező XML | |
| 394 | +állományainak egységes szerkezetű eleme, mely definiálja az állomány részére a változókat, és kapcsolatokat. | |
| 395 | +Valamint meghatározza a paraméterezés nyelvi környezetét, ha azt nem adják meg a programban. | |
| 396 | +Az XmlParser paraméterfájljainak általános felépítése és logikája a következő: | |
| 397 | +```xml | |
| 398 | +<!-- Az XmlParser gyökér paraméterfájl --> | |
| 399 | +<ParserConfig LCID="" NameSeparator=""> <!-- NameSeparator opcionális --> | |
| 400 | + <XmlParser> | |
| 401 | + <ConnectionString Name="" LCID="">...VALUE...</ConnectionString><!-- LCID opcionális --> | |
| 402 | + <XmlVar Name="" LCID="">...VALUE...</XmlVar> | |
| 403 | + <XmlVar Name="" LCID="">...VALUE...</XmlVar> | |
| 404 | + <XmlVar Name="" LCID="">...VALUE... | |
| 405 | + [<Conditions> | |
| 406 | + <Condition Type="" Test="" With="">...VALUE... | |
| 407 | + [<Conditions>...</Conditions>] | |
| 408 | + </Condition> | |
| 409 | + </Conditions>] | |
| 410 | + </XmlVar> | |
| 411 | + </XmlParser> | |
| 412 | + <Configurations> | |
| 413 | + <Configuration Name="Sample1" File="Sample1File" Element="FirstElement/SecondElement"> | |
| 414 | + <Configuration Name="Sample2" Element="Sample2Element"> <!-- File,Element valamelyik kötelező --> | |
| 415 | + <Configuration Name="Sample3" File="Sample3File"> | |
| 416 | + </Configurations> | |
| 417 | + <Sample2Element> | |
| 418 | + [<XmlParser>...<XmlParser>] | |
| 419 | + . | |
| 420 | + . | |
| 421 | + . | |
| 422 | + </Sample2Element> | |
| 423 | +</ParserConfig> | |
| 424 | +``` | |
| 425 | +Sample1File: | |
| 426 | +```xml | |
| 427 | +<Root> | |
| 428 | + [<XmlParser>...</XmlParser>] | |
| 429 | + <FirstElement> | |
| 430 | + <SecondElement> | |
| 431 | + [<XmlParser>...</XmlParser>] | |
| 432 | + . | |
| 433 | + . | |
| 434 | + . | |
| 435 | + </SecondElement> | |
| 436 | + </FirstElement> | |
| 437 | +</Root> | |
| 438 | +``` | |
| 439 | +Sample3File: | |
| 440 | +```xml | |
| 441 | +<Root> | |
| 442 | + [<XmlParser>...</XmlParser>] | |
| 443 | + . | |
| 444 | + . | |
| 445 | + . | |
| 446 | +</Root> | |
| 447 | +``` | |
| 448 | +Az osztály a lenti sorrendben és helyeken elvégzi az XmlParser elemek feldolgozását: | |
| 449 | +* Az XmlParser.xml fájl gyökerében elhelyezett XmlParser elem | |
| 450 | +* A konfiguráció által meghatározott fájl gyökér eleme alatti XmlParser elem | |
| 451 | +* A konfiguráció által meghatározott fájl és egy ottani elem alatti XmlParser elem | |
| 452 | +Az XmlVar elemek (a továbbiakban változók) egy későbbi XmlParser-ban felülírhatóak. | |
| 453 | +Másképpen fogalmazva: ha a feldolgozás során olyan változót talál, mely már egy korábbi | |
| 454 | +XmlParser-ban szerepelt, akkor annak értéke felülíródik a későbben megtalált ilyen nevű | |
| 455 | +változó értékével. Az XmlParser elemek feldolgozása után az előfeldolgozó a paraméterező XML | |
| 456 | +állományban elvégzi a változókra való hivatkozások feloldását, azaz behelyettesíti a hivatkozások | |
| 457 | +helyére a változók értékét. Utána a saját xml feldolgozó részére megtartja a tartalmat. | |
| 458 | +Az XmlParser.RootElement (XmlLinqBase.RootElement) tulajdonságában már egy olyan XML struktúra van, | |
| 459 | +amelyben a behelyettesítések el lettek végezve. Az XmlParser (XmlLinqBase) által szolgáltatott | |
| 460 | +metódusok már mind ezen az elemen dolgoznak. | |
| 461 | + | |
| 462 | +Az osztály egy absztrakt osztály, felhasználása a következő módon lehetséges: | |
| 463 | +```javascript | |
| 464 | +public class MyXmlProcessor : XmlParser | |
| 465 | +{ | |
| 466 | + public MyXmlProcessor() : base(xmlConnection, appPath, lcid, otherVars) | |
| 467 | +} | |
| 468 | +``` | |
| 469 | +* **xmlConnection** Az XmlParser kapcsolati objektum. Lásd: [XmlConnection osztály](##XmlConnection-osztaly) | |
| 470 | +* **appPath** A felhasználó alkalmazásban érvényes alkalmazás mappa. (A '~' jel értéke.) | |
| 471 | +* **lcid** A nyelvi környezetet meghatározó nyelvi kód. Ha üres, akkor az XmlParser.xml-ben megadott nyelv kód lesz alkalmazva. Ha ott sincs, akkor "en-US". | |
| 472 | +* **otherVars** Egy szótár, mely név érték párokat tartalmaznak, melyek bekerülnek az XmlVars-ok közé. | |
| 473 | + | |
| 474 | +Tulajdonság|Típus|Leírás | |
| 475 | +:----|:----|:---- | |
| 476 | +XmlVars|```VariableCollection```|Változók gyűjteménye, mely tartalmazza az összes változót az értékével együtt. | |
| 477 | +ConnectionStrings|```VariableCollection```|Kapcsolatok gyűjteménye, mely tartalmazza a struktúra összes különböző nevű kapcsolatát. | |
| 478 | +CurrentFileName|```string```|Az épp feldolgozás alatt álló Xml fájl a teljes fizikai elérési útvonalával. | |
| 479 | +Configuration|```ConfigurationType```|A megadott nevű komponens Configuration elemének értékei. | |
| 480 | + | |
| 481 | +### Beépített static osztályok | |
| 482 | + | |
| 483 | +#### XmlParser.Defaults osztály | |
| 484 | + | |
| 485 | +Állandó|Értéke|Leírás | |
| 486 | +:----|:----|:---- | |
| 487 | +XMLFILE|@"~\App_Data\XmlParser\XmlParser.xml"|Az XMLParser.xml fájl meghatározott helyének állandója. | |
| 488 | + | |
| 489 | +A controllerben a következő utasítással feloldható: ```Server.MapPath(XmlParser.Defaults.XMLFILE);``` | |
| 490 | + | |
| 491 | +### Beépített osztályok | |
| 492 | +Ha szükséges vagy hasznos, akkor a felhasználó osztály kiterjesztheti ezeket. | |
| 493 | + | |
| 494 | +#### XmlParser.ElementNames osztály | |
| 495 | +Általában használatos elemnevek kiterjeszthető osztálya. Az XmlLinqBase hasonló osztályát terjeszti ki. | |
| 496 | + | |
| 497 | +Állandó|Értéke|Leírás | |
| 498 | +:----|:----|:---- | |
| 499 | +XMLPARSER|"XmlParser"|XML tagokban lehetséges 'XmlVar' elem eléréséhez hasznos állandó. | |
| 500 | +XMLVAR|"XmlVar"|XML tagokban lehetséges 'XmlVar' elem eléréséhez hasznos állandó. | |
| 501 | +CONNECTIONSTRING|"ConnectionString"|XML tagokban lehetséges 'ConnectionString' elem eléréséhez hasznos állandó. | |
| 502 | +CONFIGURATIONS|"Configurations"|XML tagokban lehetséges 'Configurations' elem eléréséhez hasznos állandó. | |
| 503 | +CONFIGURATION|"Configuration"|XML tagokban lehetséges 'Configuration' elem eléréséhez hasznos állandó. | |
| 504 | + | |
| 505 | +#### XmlParser.AttributeNames osztály | |
| 506 | +Általában használatos attribútumnevek kiterjeszthető osztálya. | |
| 507 | + | |
| 508 | +Állandó|Értéke|Leírás | |
| 509 | +:----|:----|:---- | |
| 510 | +NAME|"Name"|XML tagokban lehetséges 'Name' attribútum eléréséhez hasznos állandó. | |
| 511 | +LCID|"LCID"|XML tagokban lehetséges 'LCID' attribútum eléréséhez hasznos állandó. | |
| 512 | +NAMESEPARATOR|"NameSeparator"|XML tagokban lehetséges 'NameSeparator' attribútum eléréséhez hasznos állandó. | |
| 513 | +FILE|"File"|XML tagokban lehetséges 'File' attribútum eléréséhez hasznos állandó. | |
| 514 | +ELEMENT|"Element"|XML tagokban lehetséges 'Element' attribútum eléréséhez hasznos állandó. | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | +## ConnectionStringStore osztály | |
| 519 | +Kapcsolati sztringek tárolójának kezelését és abban való keresést támogató osztály | |
| 520 | +az egységes használat érdekében. | |
| 521 | + | |
| 522 | +Használati minta: | |
| 523 | +```javascript | |
| 524 | +// SQL esetén | |
| 525 | +string csstring = ConnectionStringStore.GetSQL(nameOrRef); | |
| 526 | +// vagy | |
| 527 | +string csstring = ConnectionStringStore.Get(nameOrRef); | |
| 528 | + | |
| 529 | +// EF DBContext-nél használható így, ha jó az alapértelmezett kapcsolat | |
| 530 | +public ApplicationDbContext() : base(ConnectionStringStore.Get()) { } | |
| 531 | + | |
| 532 | +// Redis esetén | |
| 533 | +string csstring = ConnectionStringStore.GetRedis(nameOrRef); | |
| 534 | +// vagy | |
| 535 | +string csstring = ConnectionStringStore.Get(nameOrRef, ConnectionStringType.Redis); | |
| 536 | +``` | |
| 537 | + | |
| 538 | +Ha a "nameOrRef" paraméter null vagy üres, akkor a "VRH.ConnectionStringStore:[CSTYPE]_connectionString" | |
| 539 | +nevű kapcsolati sztringet keresi. [CSTYPE] a keresett típus szerinti érték (jelenleg SQL v. Redis). | |
| 540 | +Ha a feloldás nem jár sikerrel, akkor hiba keletkezik. | |
| 541 | + | |
| 542 | +### A keresés algoritmusa: | |
| 543 | +Az alkalmazás konfigurációs fájljában (App.config vagy Web.config) indul a keresés. | |
| 544 | + | |
| 545 | +#### 1. Konfigurációs fájl ```<connectionStrings>``` elem | |
| 546 | +A nevet megkísérli az ```<add>``` elemben megkeresni. Egy minta: | |
| 547 | +```xml | |
| 548 | +<connectionStrings> | |
| 549 | + <add name="DBConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=DBName;user id=sa;password=***;multipleactiveresultsets=True" providerName="System.Data.SqlClient" /> | |
| 550 | +</connectionStrings> | |
| 551 | +``` | |
| 552 | +Ha van olyan ```<add>``` bejegyzés, ahol a "name" attribútum egyezik a keresett névvel, | |
| 553 | +akkor a "connectionString" attribútum értéke lesz a kapcsolati sztring. | |
| 554 | + | |
| 555 | +#### 2. Konfigurációs fájl ```<appSettings>``` elem | |
| 556 | +Ha a konfigurációs fájl ```<connectionStrings>``` elemében nem találta a nevet, akkor az ```<appSettings>``` elemben keres tovább. | |
| 557 | +```xml | |
| 558 | +<appSettings> | |
| 559 | + <add key="VRH.ConnectionStringStore" value="connections.xml"/> | |
| 560 | + <add key="VRH.DBConnection" value="connections.xml/QQQ|DBConnection"/> | |
| 561 | + <add key="VRH.XmlParser:root" value="d:\!Dev\VRH\Vrh.XmlProcessing\SandBox\XmlParser.xml"/> | |
| 562 | +</appSettings> | |
| 563 | +``` | |
| 564 | +Ha van olyan ```<add>``` bejegyzés, ahol a "key" attribútum egyezik a keresett névvel, akkor a "value" attribútum értékét egy | |
| 565 | +ConnectionStringStore referenciának tekinti. Ha nem talál ilyet, akkor a nevet tekinti egy ConnectionStringStore referenciának. | |
| 566 | +A referencia megmutatja, hol található a kapcsolati sztringeket tartalmazó fájl, és azon belül az az elem, ahol meghatározott | |
| 567 | +szerkezetű kapcsolati sztring leírók megtalálhatóak. A referencia által megjelölt helyen, és az ```<XmlParser>``` elem | |
| 568 | +```<ConnectionString>``` elemeiben megadott sztringek egy gyűjteményt alkotnak, melyben a megadot nevet lehet keresni, | |
| 569 | +A gyűjteményben nem lehetnek egyforma nevek. Hiba akkor jelentkezik, ha a keresett név nem található, vagy a referencia hibás. | |
| 570 | + | |
| 571 | +#### ConnectionStringStore referencia formátuma | |
| 572 | +Teljes formátum: **[fájl az elérési útvonal] / [XMLPath] | [cselem név]** vagy rövid formátum: **[cselem név]** ahol | |
| 573 | +- **[file elérési útvonal]**: Az xml fájlhoz vezető relatív, vagy abszolút útvonal. | |
| 574 | +Ha az első karakter '@', akkor az útvonal abszolút, egyébként az exe könyvtárára relatív. | |
| 575 | +- **[XMLPath]**: A kijelölt xml fájlban a connection string store root eleméig (```<connectionStrings>```) vezető xml elem hierarchia. | |
| 576 | +A tagok "/" jellel vannak elválasztva. Tulajdonképpen az XmlParser-ból ismerős XmlConnection.Element értéke, | |
| 577 | +ezért a gyökér elem nevét nem kell megadni. | |
| 578 | +- **[cselem név]**: egy connectionString elem neve. A "name" attributum értéke. | |
| 579 | + | |
| 580 | +Abban az esetben, ha a ConnectionStringStore referencia „rövid” formátumú, akkor a "[file elérési útvonal] / [XMLpath]" karaktersorozatot a ConnectionStringStore | |
| 581 | +az App.config file ```<appSettings>``` blokkjából a "VRH.ConnectionStringStore" nevű elemből olvassa ki. Ha ilyenkor nincs ilyen, akkor az hiba. | |
| 582 | + | |
| 583 | +### Javasolt módszer | |
| 584 | +A konfigurációs fájlban létre kell hozni a kapcsolati sztring gyűjteményre mutató bejegyzést "VRH.ConnectionStringStore" kulcs értékkel. | |
| 585 | +```xml | |
| 586 | +<appSettings> | |
| 587 | + <add key = "VRH.ConnectionStringStore" value="C:\ALM\wwwroot\VRHConnections.xml/configuration"/> | |
| 588 | +</appSettings> | |
| 589 | +``` | |
| 590 | +- Az konfigurációs fájl ```<connectionStrings>``` és ```<appSettings>``` elemeiben egyéb hivatkozás szükségtelen. | |
| 591 | +- A ```Get()```, ```GetSQL()``` és ```GetRedis()``` metódusok paraméterében rövid formátumú referenciát kell megadni. | |
| 592 | +Értsd: csak a kapcsolati sztring nevét. | |
| 593 | +- Alapértelmezések használata kerülendő. | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | +## LinqXMLProcessorBase osztály | |
| 598 | +Az xml paraméterfájlok feldolgozását támogató osztály, mely eseménykezeléssel és az xml paraméterfájl változásának figyelésével is fel van vértezve. | |
| 599 | +Ha nincs elérhető XmlParser gyökérfájl, ezzel akkor is megvalósítható a feldolgozás, de akkor a behelyettesítéseket a feldolgozó osztálynak | |
| 600 | +kell elvégeznie. Elérhető XmlParser gyökérfájl esetén az xml paraméterfájl átesik az XmlParser előfeldolgozásán, vagyis az XMlParser változók | |
| 601 | +automatikusan behelyettesítve állnak rendelkezésre a feldolgozás során. | |
| 602 | + | |
| 603 | +**Feldolgozó osztály számára látható tagok** | |
| 604 | + | |
| 605 | +Tulajdonság|Típus|Leírás | |
| 606 | +:----|:----|:---- | |
| 607 | +_AppPath|```string```|A relatív útvonalak feloldó mappája. | |
| 608 | +_throwException|```bool```|Igaz értéke esetén hibák esetén exception keletkezik. Hamis érték esetén alapértelmezett értékeket eredményez a hibák elfedésére. Alapértelmezett értéke az "appSettings" "Vrh.LinqXMLProcessor.Base:ThrowExceptions" kulcs értéke. Ha ott nincs érték, akkor false. | |
| 609 | +_xmlFileDefinition|```string```|Az xml paraméter fájl fizikai elérése kiegészítve a fájlon belüli elemre hivatkozással. | |
| 610 | +_xmlNameSpace|```string```|Az xml namespace tárolására szolgáló mező. | |
| 611 | +_XmlParser_Root|```string```|XmlParser számára szükséges root fájl helyének megadása. Ha üresen hagyjuk, akkor az alapértelmezés szerinti helyen keresi az XmlParser. Ha relatív (vagyis "~" jellel kezdődik, akkor érdemes kitölteni az _AppPath tulajdonságot is. | |
| 612 | + | |
| 613 | +Metódus|Leírás | |
| 614 | +:----|:---- | |
| 615 | +```T GetAttribute<T>(XElement element, string attributeName, T defaultValue)```|Visszadja egy XElement típusban található XAttribute típus értékét az elvárt típusban. | |
| 616 | +```T GetElementValue<T>(XElement element, T defaultValue)```|Visszadja egy XElement típus értékét az elvárt típusban. | |
| 617 | +```XElement GetRootElement()```|Az xml paraméterfájl gyökér elemének XElement objektumát adja vissza ez a függvény. | |
| 618 | +```IEnumerable<XElement> GetAllXElements(params string[] elementPath)```|Visszaadja a paraméterek által kijelölt útvonal alatt lévő összes, az utolsó paraméterben megnevezett TAG-et | |
| 619 | +```XElement GetXElement(params string[] elementPath)```|Visszadja a gyökér elemtől megadott elemeken át elérhető XElement objektumot. | |
| 620 | +```T GetValue<T>(string stringValue, T defultValue)```|A megadott típusra konvertál egy sztringet, ha a konverzió lehetséges. | |
| 621 | + | |
| 622 | +> A metódusok felsorolása nem teljes!!!. | |
| 623 | + | |
| 624 | + | |
| 625 | +### A korábbi dokumentáció | |
| 626 | +Ez a leírás a komponens **v1.2.1** kiadásáig bezáróan naprakész. | |
| 627 | +Igényelt minimális framework verzió: **4.0** | |
| 628 | +Teljes funkcionalítás és hatékonyság kihasználásához szükséges legalacsonyabb framework verzió: **4.0** | |
| 629 | +#### Ez a komponens arra szolgál, hogy az XML-ben tárolt beállítások, paraméterek feldolgozása egységes legyen, és a következő elveket kényszerítse: | |
| 630 | +* ##### A paraméter feldolgozás tisztán OOP-elvű legyen | |
| 631 | +* ##### Kerüljön kiemelésre egy külön osztályba, amelynek ez a scopja. Így a megvalósítás még véletlenül se legyen összeépítve a felhasználási hely feladataival, megsértve ezzel a Single Responsibility elvet. | |
| 632 | +* ##### A használt megoldás semmilyen módon ne legyen változás érzékeny, hibatürő legyen. (Ne serializációra épüljön.) | |
| 633 | +* ##### Kevés implementáció függő kód írásával adjon eredményt. | |
| 634 | + | |
| 635 | +Használatára ez a kód minta (a kód részlet copyzható az üjabb paraméter fájlfeldolgoztó kiindulási mintajéként): | |
| 636 | + | |
| 637 | +```javascript | |
| 638 | +using System.Collections.Generic; | |
| 639 | +using System.Xml.Linq; | |
| 640 | +using Vrh.LinqXMLProcessor.Base; | |
| 641 | + | |
| 642 | +/// TODO: Változtasd meg a felhasználási helynek megfelelő névtérre | |
| 643 | +namespace YourNameSpace | |
| 644 | +{ | |
| 645 | + // TODO: Töröld az instrukciós megjegyzéseket (TODO) a production-level kódból, miután elvégezted a bennük foglaltakat! | |
| 646 | + | |
| 647 | + /// <summary> | |
| 648 | + /// TODO: Mindig nevezd át ezt az osztályt!!! | |
| 649 | + /// Használd az osztályra vonatkozó elnevezési konvenciókat, beszédes neveket használj a DDD (Domain Driven Development) alapelveinek megfelelően! | |
| 650 | + /// Naming pattern: {YourClassName}XmlProcessor | |
| 651 | + /// Mindig használd az XmlProcessor suffix-et! | |
| 652 | + /// </summary> | |
| 653 | + public class YourClassNameXmlConfigProcessor : LinqXMLProcessorBaseClass | |
| 654 | + { | |
| 655 | + /// <summary> | |
| 656 | + /// Constructor | |
| 657 | + /// TODO: Nevezd át az osztály nevére! | |
| 658 | + /// </summary> | |
| 659 | + /// <param name="parameterFile">XML fájl aminek a feldolgozására az osztály készül</param> | |
| 660 | + public YourClassNameXmlConfigProcessor(string parameterFile) | |
| 661 | + { | |
| 662 | + _xmlFileDefinition = parameterFile; | |
| 663 | + } | |
| 664 | + | |
| 665 | + #region Retrive all information from XML | |
| 666 | + | |
| 667 | + // TODO: Írd át vagy töröld ezeket a meglévő példa implemenmtációkat! Az alapelveket bent hagyhatod, hogy később is szem előtt legyenek! | |
| 668 | + // Alapelvek: | |
| 669 | + // - Mindig csak olvasható property-ket használj getter megvalósítással, ha az adat visszanyeréséhez nem szükséges paraméter átadása! | |
| 670 | + // - Csak akkor használj függvényeket, ha a paraméterek átadására van szükség az információ visszanyeréséhez! | |
| 671 | + // - Mindig légy típusos! Az alaposztály jelenlegi implementációja (v1.1.X) az alábbi típusokat kezeli: int, string, bool, Enumerátor (generikusan)! Ha típus bővítésre lenne szükséged, kérj fejlesztést rá (change request)! | |
| 672 | + // - Bonyolultabb típusokat elemi feldolgozással építs! Soha ne használj XML alapú szérializációt, amit depcreatednek tekintünk a fejlesztési környezeteinkben! | |
| 673 | + // - A bonyolultabb típusok kódját ne helyezd el ebben a fájlban, hanem külső definíciókat használj! | |
| 674 | + // - Ismétlődő információk visszanyerésére (listák, felsorolások), generikus kollekciókat használj (Lis<T>, Dictonary<Tkey, TValue>, IEnumerable<T>, stb...) | |
| 675 | + | |
| 676 | + /// <summary> | |
| 677 | + /// TODO: Írd felül, vagy töröld ezt a példát! | |
| 678 | + /// Egyszerű boolean érték visszanyerése adott element értékéből | |
| 679 | + /// </summary> | |
| 680 | + public bool Property1 | |
| 681 | + { | |
| 682 | + get | |
| 683 | + { | |
| 684 | + return GetExtendedBoolElementValue(GetXElement(PROPERTY1_ELEMENT_NAME), true); | |
| 685 | + } | |
| 686 | + } | |
| 687 | + | |
| 688 | + /// <summary> | |
| 689 | + /// TODO: Írd felül, vagy töröld ezt a példát! | |
| 690 | + /// Egyszerű boolean érték visszanyerése adott element alatti atribute értékéből | |
| 691 | + /// </summary> | |
| 692 | + public bool Property2 | |
| 693 | + { | |
| 694 | + get | |
| 695 | + { | |
| 696 | + return GetExtendedBoolAttribute(GetXElement(PROPERTY1_ELEMENT_NAME), ATTRIBUTE1_ATTRIBUTE_IN_PROPERTY1_ELEMENT, false, "1", "yes"); | |
| 697 | + } | |
| 698 | + } | |
| 699 | + | |
| 700 | + /// <summary> | |
| 701 | + /// TODO: Írd felül, vagy töröld ezt a példát! | |
| 702 | + /// Lista visszaadása ismétlődő XML elemekből. | |
| 703 | + /// </summary> | |
| 704 | + public List<string> AllStrings | |
| 705 | + { | |
| 706 | + get | |
| 707 | + { | |
| 708 | + List<string> returnList = new List<string>(); | |
| 709 | + foreach (var item in GetAllXElements(STRINGS_ELEMENT_NAME)) | |
| 710 | + { | |
| 711 | + returnList.Add(GetStringElementValue(GetXElement(STRING_ELEMENT_NAME))); | |
| 712 | + } | |
| 713 | + return returnList; | |
| 714 | + } | |
| 715 | + } | |
| 716 | + | |
| 717 | + /// <summary> | |
| 718 | + /// TODO: Írd felül, vagy töröld ezt a példát! | |
| 719 | + /// Arra példa, hogy mikor használjunk metódust, property helyett: ha az adott információ visszanyeréséhez valamilyen paramétert akarunk felhasználni. | |
| 720 | + /// Használjunk Get prefixet ezen metódusok nevében! Adjunk DDD leveknek megfelelő beszédes neveket! | |
| 721 | + /// </summary> | |
| 722 | + /// <param name="group"></param> | |
| 723 | + /// <returns></returns> | |
| 724 | + public List<string> GetStringsUnderGroup(string group) | |
| 725 | + { | |
| 726 | + List<string> returnList = new List<string>(); | |
| 727 | + foreach (var item in GetAllXElements(STRINGS_ELEMENT_NAME)) | |
| 728 | + { | |
| 729 | + if (GetStringAttribute(item, GROUP_ATTRIBUTE_IN_STRING_ELEMENT) == group) | |
| 730 | + { | |
| 731 | + returnList.Add(GetStringElementValue(GetXElement(STRING_ELEMENT_NAME))); | |
| 732 | + } | |
| 733 | + } | |
| 734 | + return returnList; | |
| 735 | + } | |
| 736 | + | |
| 737 | + #endregion | |
| 738 | + | |
| 739 | + #region Defination of namming rules in XML | |
| 740 | + // A szabályok: | |
| 741 | + // - Mindig konstansokat használj, hogy az element és az attribútum neveket azon át hivatkozd! | |
| 742 | + // - Az elnevezések feleljenek meg a konstansokra vonatkozó elnevetési szabályoknak! | |
| 743 | + // - Az Attribútumok neveiben mindig jelöld, mely elem alatt fordul elő. | |
| 744 | + // - Az elemekre ne használj, ilyet, mert az elnevezések a hierarchia mélyén túl összetetté (hosszúvá) válnának! Ez alól kivétel, ha nem egyértelmű az elnevezés e nélkül. | |
| 745 | + // | |
| 746 | + | |
| 747 | + //TODO: Töröld, vagy írd felül ezeket a példa konstansokat! | |
| 748 | + private const string PROPERTY1_ELEMENT_NAME = "Property1"; | |
| 749 | + private const string ATTRIBUTE1_ATTRIBUTE_IN_PROPERTY1_ELEMENT = "Attribute1"; | |
| 750 | + private const string STRINGS_ELEMENT_NAME = "Strings"; | |
| 751 | + private const string STRING_ELEMENT_NAME = "String"; | |
| 752 | + private const string GROUP_ATTRIBUTE_IN_STRING_ELEMENT = "Group"; | |
| 753 | + | |
| 754 | + #endregion | |
| 755 | + } | |
| 756 | +} | |
| 757 | +``` | |
| 758 | +Felhasználáskor: | |
| 759 | +* Töröld a TODO megjegyzéseket, miután végrehajtottad őket! | |
| 760 | +* Csak valós kódot hagyj az osztályban, a példákat töröld, vagy írd át valós elemekre! | |
| 761 | +* A szabályokra vonatkozó instrukciókat célszerűen hagyd meg a kommentekben, hogyha bárki a jövőben bővíti a feldolgozó osztályt, akkor a szeme előtt legyenek a szabályok. | |
| 762 | +* Mindig hazsnálj XML commenteket! (Ahogy minden production Level code-ban! Ez egy erős kóddal kapcsolkatos "DONE" feltétel nálunk!) | |
| 763 | + | |
| 764 | +#### Hibaérzékenység bekapcsolása: | |
| 765 | +A komponens alapértelmezésben hibatűrő müködésű, ha a konfigurációs fájlban hiányoznak a keresett információk, akkor defultokat ad. | |
| 766 | +Azonban bekapcsolhatjuk, hogy az adott környezetben kivételerket dobjon, mikor a konfiguráció oldalon nem talál meg valamit. | |
| 767 | +Ezt vagy ugy érjük el, ha a környezet konfigurációjában (App.config, Web.config) elérhető egy Vrh.LinqXMLProcessor.Base:ThrowExceptions app settings kulcs, amelynek értéke true. | |
| 768 | +Vagy a leszármazott osztályban true-ra állkítjuk a _throwException protected property értékét. Figyelem, a property értékének beállítása után nem veszi többé figyelembe a fent írt app settings kulcs értékét. | |
| 769 | + | |
| 770 | +Ha hibaérzékenység nem, de például logolás szükséges, akkor ezt a ConfigProcessorEvent eseményre építve lehet felépíteni. A kompones ezen az eseméynen át minden esetben jelzéstz küld a fellépő konfigurációs hibákról, amik miatt defult értékeket használ az adott konfigurációs beállításra. | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | +*** | |
| 775 | +## Version History: | |
| 776 | +### 1.18.4 (2020.10.26) Patch: | |
| 777 | +- Az XmlConnection példányt nem írhatjuk felül büntetlenül, hiszen bizonyos alkalmazások meg pont arra számítanak, hogy ott az általuk ismert érték marad benne. | |
| 778 | +Az XmlParser.Configuration protected tulajdonság pont arra való, hogy az XmlParser származtatott osztályaiban a feloldott értékeket el lehessen érni. | |
| 779 | +- Bevezetésre került az XmlParser.Configuration-ben a "Root" tulajdonság, így minden XmlConnection-ban is megadható tulajdonság feloldott értéke elérhető a típusban. | |
| 780 | + | |
| 781 | +### 1.18.3 (2020.04.30) Patch: | |
| 782 | +- Annak a hibának a javítása, hogy a config=xxxx; típusú connectionstring-ek esetén az XmlConnection példány File és Element mezői nem kerültek | |
| 783 | +kitöltésre, és ez a LinqXMLProcessingBase osztályon belül hibát okozott; a hiba javítása csak a megtapasztalt Exception elhárítására szorítkozik, | |
| 784 | +de szerintem a teljes javítás igényelné, hogy az XmlConnection példány konstruktorai a connectionstring-et teljesen feloldják és ezeket a mezőket is kitöltsék! | |
| 785 | + | |
| 786 | +### 1.18.2 (2020.03.30) Patch: | |
| 787 | +- Apró javítás a "nuspec" és az "AddToTestNuGetPackages.ps1" fájlban. | |
| 788 | + | |
| 789 | +### 1.18.1 (2020.03.30) Patch: | |
| 790 | +- NameSpace használatának kivétele az XmlLinqBase osztályból. | |
| 791 | + | |
| 792 | +### 1.18.0 (2020.03.28) Compatible changes: | |
| 793 | +- XmlParser osztály kiegészült a publikus "RootElementName" tulajdonsággal, mely a megnyitott fájl gyökér elemének nevét tartalmazza. | |
| 794 | +Egy XPath kifejezés összeállításához használható, mert ott szükséges a gyökér nevét is megadni egy elem vagy attribútum eléréséhez. | |
| 795 | +- Most már kap értéket a publikus "CurrentXmlConnectionString" tulajdonság abban az esetben is, ha XmlConnection típussal példányosítottak. | |
| 796 | +- Frissítés az MSTest.TestAdapter 2.1.0 változatára. (Ez csak a Test projektet érinti!) | |
| 797 | +- Frissítés az MSTest.TestFramework 2.1.0 változatára. (Ez csak a Test projektet érinti!) | |
| 798 | +- NuGet csomag módosítása úgy, hogy a modul ReadMe.md "Build Action" tulajdonsága "None" legyen a telepítés után. Install.ps1 hozzáadása. | |
| 799 | + | |
| 800 | +### 1.17.0 (2020.02.14) Compatible change: | |
| 801 | +- XmlParser osztály kiegészült a publikus CurrentXmlConnectionString-gel, ami a konstruktornak átadott xml connectionstring-et tartalmazza. | |
| 802 | + | |
| 803 | +### 1.16.0 (2020.02.10) Compatible change: | |
| 804 | +- Az eddig m_BaseFolder privát field átalakítása BaseFolder public attributummá. | |
| 805 | + | |
| 806 | +### 1.15.4 (2020.02.04) Patches: | |
| 807 | +- A ConnectionStringStore exception-ök sztenderdizálása, plusz info beillesztése a szövegekbe | |
| 808 | + | |
| 809 | +### 1.15.4 (2020.01.31) Patches: | |
| 810 | +Ha nincs megadva az AppPath paraméter, akkor alapértelmezést használt, ami azonban bizonyos esetekben nem működött, | |
| 811 | +mert a "System.Reflection.Assembly.GetEntryAssembly()" metódus null értékkel tért vissza (pl. amikor a WebALM-et hívtuk a LearALMNew-ból). | |
| 812 | +Ez a kód volt: | |
| 813 | +```javascript | |
| 814 | +if (string.IsNullOrEmpty(xmlparserapppath)) | |
| 815 | +{ | |
| 816 | + this._AppPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly()?.Location); | |
| 817 | +} | |
| 818 | +else | |
| 819 | +{ | |
| 820 | + this._AppPath = xmlparserapppath; | |
| 821 | +} | |
| 822 | +``` | |
| 823 | +És ez kellett helyette (nem biztos, hogy ez a tökéletes megoldás, lehet, hogy egyes esetekben még így is problémás, | |
| 824 | +ha pl. ha nem webalkalmazások esetén fordul elő a fenti null értékes hívás!!!!!!!!!) | |
| 825 | +```javascript | |
| 826 | +if (string.IsNullOrEmpty(xmlparserapppath)) | |
| 827 | +{ | |
| 828 | + this._AppPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly()?.Location); | |
| 829 | + if (this._AppPath == null) this._AppPath = HttpContext.Current.Server.MapPath("~"); | |
| 830 | +} | |
| 831 | +else | |
| 832 | +{ | |
| 833 | + this._AppPath = xmlparserapppath; | |
| 834 | +} | |
| 835 | +``` | |
| 836 | + | |
| 837 | +### 1.15.3 (2020.01.31) Patches: | |
| 838 | +- LinqXMLProcessorBaseCommonOrInstance osztályban a GetXElement és GetAllXElement metódusokban hiba javítása. | |
| 839 | + | |
| 840 | +### 1.15.3 (2020.01.23) Patches: | |
| 841 | +- LinqXMLProcessorBaseCommonOrInstance osztályban a GetXElement és GetAllXElement metódusokból a felesleges generikus kivétele | |
| 842 | + | |
| 843 | +### 1.15.1 (2020.01.22) Patches: | |
| 844 | +- Vissza lett téve az XmlLinqBase osztályba a GetXmlPath metódus. | |
| 845 | + | |
| 846 | +### 1.15.0 (2020.01.20) | |
| 847 | +#### ConnectionStringStore: | |
| 848 | +- Több connectionString xml elem lehet, mindegyikben több connectionString elemmel; funkciója mindössze annyi, hogy a ConnectionStringStore | |
| 849 | +Xml file-ban a connection string-ek ezáltal csoportosítva írhatók be, a blokkok-ban levő connections string-ek végül is egy közös listába kerülnek, ahogy eddig is. | |
| 850 | +- Az appconfig file-ok másolása funkció kibővült azzal, hogy meg lehet adni a másolandó file-ok nevét a ConnectionStringStore xml file | |
| 851 | +appconfigFileDistribution elemében (az elem értéke vesszővel elválasztott név lista, és/vagy az appconfigFileDistribution elemen belüli | |
| 852 | +File elemek sorozatában megadott nevek (a File elemek mindegyike csak egy file nevet tartalmazhat); eddig ezek a nevek be voltak drótozva, | |
| 853 | +ezért ez a funkció inkább főverzió-szám emelést igényelne, de spóroljunk a számokkal... | |
| 854 | +- A másolás csak akkor történik meg, ha az appconfigFileDistribution/Enable= attributuma true értékű. | |
| 855 | +- A másolás csak az app domain indulása utáni első ConnectionStringStore híváskor történik meg (ez web-es hívások esetén különösen "praktikus"), | |
| 856 | +kivéve, ha az appconfigFileDistribution/Force= attributum értéke is true, mert ebben az esetben mindenképpen másol, tehát akkor is, ha a | |
| 857 | +file-ok már ott vannak. Azt, hogy a file-ok ott vannak-e, a file-ok összehasonlításával dönti el, majd az összehasonlítás eredményét egy | |
| 858 | +appdomain változóban meg is jegyzi. | |
| 859 | +v1.14.xxx: kimaradt | |
| 860 | + | |
| 861 | +### 1.13.1 (2020.01.19) | |
| 862 | +- hiba javítása | |
| 863 | +- xml connectionstringet, amiben csak file, vagy file+element tagok vannak le lehet írni "@c:\F1\F2\xmlfile.xml/xmltag1/xmltag2" formában | |
| 864 | +ami egyenértékű a "file=c:\F1\F2\xmlfile.xml; element=xmltag1/xmltag2;" leírással; | |
| 865 | +- ezen leírás esetén a root elemet az appconfigból veszi, az egyéb xml parser tagok nem használhatók. | |
| 866 | + | |
| 867 | +### 1.13.0 (2020.01.02) | |
| 868 | +- Az XmlParser alapú xml feldolgozásba a LinqXMLProcessorBase-zel azonos funkcionalitású (de nem teljesen azonos nevű) | |
| 869 | +újabb metódusok beépítése: GetRootElement, GetAllXelement, GetExtendedStringValue, GetExtendedBoolValue | |
| 870 | + | |
| 871 | +### 1.12.0 (2019.11.28) | |
| 872 | +- wcf uri connectionstring elemben a distributecfgfiles tag bevezetése, alapértelmezés true | |
| 873 | + | |
| 874 | +### 1.11.0 (2019.11.20) | |
| 875 | +- WCF osztály változtatása / Kialakításra került az a funkció, amely a központi helyen (a ConnectionStringStore-t tartalmazó | |
| 876 | +könyvtárból) a futó alkalmazás aktív appconfig file-ja mellé másolja a WCFServices.config,WCFClients.config,WCFBindings.config | |
| 877 | +és WCFBehaviors.config file-okat, amelyek a nevüknek megfelelő xml struktúrákat tartalmazzák. Ezeknek a file-oknak a | |
| 878 | +használatához szükséges, hogy az appconfig file-ban a Service.Model elemen belül a Services, Clients, Bindings és Behaviors | |
| 879 | +elemek ezekre a külső fileokra hivatkozzanak, | |
| 880 | +- WCF osztály változtatása / public static bool EnableDistributeWCFConfigFiles property bevezetése. Alalpértelmezése true. | |
| 881 | +Ennek értékével lehet szabályozni, hogy a WCF inicializáló hívások a központi WCF konfigurációs file-okat bemásolják-e a web | |
| 882 | +alkalmazás web.config file-ja mellé. | |
| 883 | + | |
| 884 | +### 1.6.0 (2019.10.30) Compatible changes: | |
| 885 | +- VariableDictionary osztályban alapértelmezett (paraméter nélküli) konstruktor bevezetése. Az osztály betűérzékeny lesz, rendszerváltozók nélkül, az alapértelmezett "@@" név szeparátorral. | |
| 886 | +- VariableDictionary osztályban új konstruktor bevezetése, mely a beépített Configuration osztályt várja paraméternek, mely meghatározza a betűérzékenységet, rendszerváltozók létrejöttét, a név elválasztót, és két rendszerváltozó (LCID,USERNAME) értékét. | |
| 887 | + | |
| 888 | +### 1.5.8 (2019.10.25) Patches: | |
| 889 | +- Lemaradt Install.ps1 script pótlása a Nuget csomagban | |
| 890 | + | |
| 891 | +### 1.5.7 (2019.10.25) Patches: | |
| 892 | +- A nuget csomag telepítéskor elkészíti azt a minimális konfigurációt, ami a telepítés helyén való instant működőképességhez szükséges. (**Minden Nuget csomagnak ez lenne a célja a belézárt komponenst illetően: A telepítés teljes automatizálása, ami azonnali használatbavételt tesz lehetővé a telepítés helyén a komponens mélyebb ismerete (pl. konfigurálás módja) nélkül!**) | |
| 893 | + | |
| 894 | +#### 1.5.6 (2019.10.01) Patches: | |
| 895 | +- Az XmlConnection összefűzős konstruktorán kellett javítani. Az elsődleges sztringből nem vette figyelembe a Root elemet. | |
| 896 | + | |
| 897 | +#### 1.5.5 (2019.09.25) Patches: | |
| 898 | +- A Get(string,string) metódus megszüntetésre került, mert a ConnectionStringType egy publikus enum, ami mindig elérhető. | |
| 899 | + | |
| 900 | +#### 1.5.4 (2019.09.15) Patches: | |
| 901 | +- A relatív útvonal feloldásában talált hiba javítása. | |
| 902 | + | |
| 903 | +#### 1.5.3 (2019.09.13) Patches: | |
| 904 | +- ConnectionStringStore kiegészült az MSMQ,EmailServer és TCPIPsocket típusokkal és az ezekhez tartozó Get függvényekkel. | |
| 905 | +- Beépítésre került egy Get(string,string) függvény is, amely string formában fogadja az enum értékek string megfelelőit | |
| 906 | + | |
| 907 | +#### 1.5.2 (2019.09.11) Patches: | |
| 908 | +- XmlLinqBase GetXElement metódusa újabb túlterheléseket kapott. Lásd dokumentáció. | |
| 909 | + | |
| 910 | +#### 1.5.1 (2019.09.03) Patches: | |
| 911 | +- XmlParser inicilizálásakor fellépő hiba esetén megmutatja az aktuális kapcsolati sztringet. Az eredeti hiba az InnerException-ben. | |
| 912 | +- XElement.Load hiba esetén a fájl nevét is meg lehet tudni. Az eredeti hiba az InnerException-ben. | |
| 913 | + | |
| 914 | +#### 1.5.0 Compatible changes: | |
| 915 | +- EmailServer connectionstring hozzáadása | |
| 916 | +- LinqProcessorBase osztályhoz új konstruktor, amely xmlparser connection stringet fogad el paraméternek | |
| 917 | + | |
| 918 | +#### 1.4.2 (2019.08.11) Patches: | |
| 919 | +- XElement értékének beolvasásakor az xml escape karaktereket most már visszaalakítja. | |
| 920 | + | |
| 921 | +#### 1.4.1 (2019.08.08) Patches: | |
| 922 | +- A ConnectionStringStore xml struktúra helyét eddig csak egy speciális string-gel lehetett kijelölni, most meg XmlParser connection stringgel IS lehet. | |
| 923 | +Eddig ez volt a forma: c:\A\B\cstorefile.xml/E1/E2/E3|CSname, emellett most ez is lehet:file=c:\A\B\cstorefile.xml;element=E1/E2/E3;|CSname | |
| 924 | +A CSStoreReference osztály-t egyenlőre nem szüntettem meg, hanem abba beletettem mindkét formátum kezelését. | |
| 925 | +A CSStoreReference osztály előállít egy XmlConnection struktúrát, amit vagy az egyik fajta, vagy a másik fajta formátum alapján csinál meg. | |
| 926 | +A formátumot meg felismeri arról, hogy van-e benne "=" jel. | |
| 927 | + | |
| 928 | +#### 1.4.0 (2019.08.01) Compatible changes: | |
| 929 | +- "id" elem bevezetése a kapcsolati sztringben. A hivatkozott elemet "Id" attribútuma alapján keresi. | |
| 930 | +- "preset" elem bevezetése a kapcsolati sztringben. A "Preset" nélküli és a "preset" elemmel egyező XmlVar-ok kerülnek a változók közé. | |
| 931 | +- Új konstruktor, mely egy megadott példányhoz fűzi a megadott kapcsolati sztringet. | |
| 932 | +- Merge() metódus elkészítése, mely a meglevő objektumhoz fűzi a megadott kapcsolati sztringet. | |
| 933 | +- "ConnectionStrings" elem feldolgozása kikerült, a továbbiakban nincs ConnectionStrings gyűjtemény az XmlParser-ban. | |
| 934 | +- A ConnectionStrings tulajdonság megmaradt "Obsolete" jelöléssel, a kompatibilitás miatt, de mindig null lesz. | |
| 935 | +- Tartalmazhat "config" esetén is "file" vagy egyéb elemet a kapcsolati sztring, mely felülírja/kiegészíti a "Configuration"-ban talált értékeket. | |
| 936 | +- A HOURSBACK és a MINUTESBACK rendszerváltozók hozzáadása. | |
| 937 | + | |
| 938 | +#### 1.3.0 (2019.06.19) Compatible changes: | |
| 939 | +- A ConnectionsStringStore a jövőben nem ad vissza alapértelmezéseket. | |
| 940 | +- SQL típus esetén a név nélkül meghívott Get metódusok a "VRH.ConnectionStringStore:SQL_connectionString" nevű kapcsolati sztringet keresik. Ha nem található, akkor hiba keletkezik. | |
| 941 | +- Redis típus esetén a név nélkül meghívott Get metódusok a "VRH.ConnectionStringStore:Redis_connectionString" nevű kapcsolati sztringet keresik. Ha nem található, akkor hiba keletkezik. | |
| 942 | + | |
| 943 | +#### 1.1.1 (2019.06.14) Patches: | |
| 944 | +- Dokumentáció frissítése. | |
| 945 | + | |
| 946 | +#### 1.1.0 (2019.06.14) Compatible changes: | |
| 947 | +- A VRH.ConnectionStringStore névtérből a "VRHConnectionStringStore" osztály áthelyezése a Vrh.XmlProcessing névtér "ConnectionStringStore" nevű osztályba. | |
| 948 | +- A ConnectionStringStore XML átesik az XmlParser előfeldolgozásán, ha van elérhető XmlParser gyökér fájl. | |
| 949 | +- A Vrh.LinqXMLProcessor.Base névtérből a "LinqXMLProcessorBaseClass" osztály áthelyezése a Vrh.XmlProcessing névtér "LinqXMLProcessorBase" nevű osztályába. | |
| 950 | +- Ha van elérehtő XmlParser gyökér fájl, akkor a LinqXMLProcessorBase átesik az XmlParser előfeldolgozásán. | |
| 951 | +- Dokumentáció frissítése. | |
| 952 | + | |
| 953 | +#### 1.0.0 (2019.05.14) Initial version: | |
| 954 | +- A Vrh.Web.Common.Lib 1.18.1-es változatában lévő változatból készült. A Vrh.Web.Common.Lib 2.0-ás változatában már nem fog szerepelni. | |
| 955 | +- Ha az XmlParser connection string nem tartalmaz root elemet, akkor az alapértelmezést elsődlegesen az alkalmazás appconfig file-jában levő "VRH.XmlParser:root" nevű elemből veszi ki. Ha ilyen elem nem létezik, vagy a tartalma üres, akkor használja a programba bedrótozott "~\App_Data\XmlParser\XmlParser.xml" értéket | |
| 956 | +- Dokumentáció frissítése. | |
| 957 | +- ReadMe.md-ből a "csharp" jelölések cseréje "javascript"-re. | |
| 958 | + | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/WebApplicationManager.cs
0 → 100644
| ... | ... | @@ -0,0 +1,939 @@ |
| 1 | +using System; | |
| 2 | +using System.IO; | |
| 3 | +using System.Collections.Generic; | |
| 4 | +using System.Linq; | |
| 5 | +using System.Text; | |
| 6 | +using System.Threading.Tasks; | |
| 7 | +using System.Threading; | |
| 8 | + | |
| 9 | +using Microsoft.Web.Administration; | |
| 10 | +using System.Management; | |
| 11 | +using System.Diagnostics; | |
| 12 | + | |
| 13 | +using Vrh.XmlProcessing; | |
| 14 | +using System.Xml.Linq; | |
| 15 | + | |
| 16 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
| 17 | +{ | |
| 18 | + #region WebApplicationManager | |
| 19 | + public static class WebApplicationManager | |
| 20 | + { | |
| 21 | + #region public method: Execute | |
| 22 | + public static object Execute(object o1=null,object o2=null) | |
| 23 | + { | |
| 24 | + string xmlcs = "file=Config.xml;element=WebApplications;"; | |
| 25 | + var config = new WebApplicationManagerXmlProcessor(xmlcs, "", "hu-HU"); | |
| 26 | + | |
| 27 | + var menufunctions = new Menu("Manage Web Applications","Select the management function!") | |
| 28 | + .AddMenuItem(new Menu.Item("WAR", "Register WebApplication",Register)) | |
| 29 | + .AddMenuItem(new Menu.Item("WAU", "Unregister WebApplication",Unregister)) | |
| 30 | + .AddMenuItem(new Menu.Item("WAI", "Set impersonate identity",SetImpersonateIdentity)) | |
| 31 | + .AddMenuItem(new Menu.Item("APS", "Start application Pool",PoolStart)) | |
| 32 | + .AddMenuItem(new Menu.Item("APF", "Stop application Pool",PoolStop)) | |
| 33 | + .AddMenuItem(new Menu.Item("APR", "Recycle application Pool",PoolRecycle)) | |
| 34 | + .AddMenuItem(new Menu.Item("WSS", "Start website",SiteStart)) | |
| 35 | + .AddMenuItem(new Menu.Item("WSF", "Stop website",SiteStop)) | |
| 36 | + .AddMenuItem(new Menu.Item("APU", "Set pool user account",PoolSetUserAccount)) | |
| 37 | + .AddMenuItem(new Menu.Item("R", "Restart website and pool",Restart)) | |
| 38 | + .SetSelectionMode(Menu.SelectionMode.Single); | |
| 39 | + | |
| 40 | + var menuapplications = new Menu("Web applications","Select the web application(s) to manage!") | |
| 41 | + .SetMenuItemDisplayer(DisplayWebAppInfo) | |
| 42 | + .SetSelectionMode(Menu.SelectionMode.Multi) | |
| 43 | + .SetHeaderWidth(4); | |
| 44 | + | |
| 45 | + while (true) | |
| 46 | + { | |
| 47 | + List<WebApplication> wadefList = config.GetDefinitionList(); | |
| 48 | + Menu.Selection sr; | |
| 49 | + using (ServerManager sm = new ServerManager()) | |
| 50 | + { | |
| 51 | + var sites = sm.Sites; | |
| 52 | + var pools = sm.ApplicationPools; | |
| 53 | + menufunctions.DisplayTitle(); | |
| 54 | + | |
| 55 | + menuapplications.ClearMenuItemList(); | |
| 56 | + foreach (var wadef in wadefList) | |
| 57 | + { | |
| 58 | + var w = WebApplicationManagerCore.CollectWebAppInfo(sites, pools, wadef); | |
| 59 | + menuapplications.AddMenuItem(new Menu.Item(null, null, null, w)); | |
| 60 | + } | |
| 61 | + } | |
| 62 | + menuapplications.DisplayItems(1); | |
| 63 | + | |
| 64 | + menufunctions.DisplayItems(3,35); | |
| 65 | + sr = menufunctions.Select(); | |
| 66 | + if (sr.Result == Menu.SelectionResult.Exit) { break; } | |
| 67 | + else if (sr.Result == Menu.SelectionResult.None) { continue; } | |
| 68 | + else if (sr.Result == Menu.SelectionResult.Error) { continue; } | |
| 69 | + var functionexecutor = menufunctions.GetExecutor(sr.SelectedKeyList.First()); | |
| 70 | + | |
| 71 | + foreach (var mi in menuapplications.MenuItemList) { mi.Executor=functionexecutor; } | |
| 72 | + | |
| 73 | + sr = menuapplications.Select(); | |
| 74 | + if (sr.Result == Menu.SelectionResult.Exit) { break; } | |
| 75 | + else if (sr.Result == Menu.SelectionResult.None) { continue; } | |
| 76 | + else if (sr.Result == Menu.SelectionResult.Error) { continue; } | |
| 77 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 78 | + else { } | |
| 79 | + menuapplications.Execute(sr.SelectedKeyList); | |
| 80 | + } | |
| 81 | + return null; | |
| 82 | + } | |
| 83 | + #endregion public method: Execute | |
| 84 | + #region private method: DisplayWebAppInfo | |
| 85 | + private static object DisplayWebAppInfo(object waobj,int lineix) | |
| 86 | + { | |
| 87 | + WebApplication wa = waobj as WebApplication; | |
| 88 | + if (lineix==0) | |
| 89 | + { | |
| 90 | + ColorConsole.WriteLine($"{wa.Xml_Description}", ConsoleColor.Black, ConsoleColor.White); | |
| 91 | + } | |
| 92 | + else if (lineix == 1) | |
| 93 | + { | |
| 94 | + ColorConsole.Write($"Web app:"); | |
| 95 | + ColorConsole.Write($"{wa.Xml_AppName}", ConsoleColor.Cyan); | |
| 96 | + var fc2 = wa.ApplicationState.Contains("Unregistered") ? ConsoleColor.Red : ConsoleColor.Green; | |
| 97 | + ColorConsole.Write($"{wa.ApplicationState}", fc2, bracket: "()"); | |
| 98 | + ColorConsole.Write($", Log.path:"); | |
| 99 | + ColorConsole.Write($"{wa.ApplicationPath}", ConsoleColor.White); | |
| 100 | + ColorConsole.Write($", Phy.path:"); | |
| 101 | + ColorConsole.WriteLine($"{wa.Xml_AppPhysicalPath}", ConsoleColor.White); | |
| 102 | + } | |
| 103 | + else if (lineix == 2) | |
| 104 | + { | |
| 105 | + ColorConsole.Write($"impersonate identity:"); | |
| 106 | + ColorConsole.WriteLine($"{wa.AppImpersonateIdentity}", ConsoleColor.White); | |
| 107 | + } | |
| 108 | + else if (lineix == 3) | |
| 109 | + { | |
| 110 | + ColorConsole.Write($"Site:"); | |
| 111 | + ColorConsole.Write($"{wa.Xml_SiteName}", ConsoleColor.Cyan); | |
| 112 | + var fc0 = | |
| 113 | + wa.SiteState.Contains("Started") ? ConsoleColor.Green | |
| 114 | + : wa.SiteState.Contains("Unregistered") ? ConsoleColor.Red | |
| 115 | + : ConsoleColor.Yellow; | |
| 116 | + ColorConsole.Write($"{wa.SiteState}", fc0, bracket: "()"); | |
| 117 | + ColorConsole.Write($", Ports:"); | |
| 118 | + ColorConsole.Write($"{wa.SitePortList}", ConsoleColor.White); | |
| 119 | + ColorConsole.Write($", Phy.path:"); | |
| 120 | + ColorConsole.WriteLine($"{wa.Xml_SitePhysicalPath}", ConsoleColor.White); | |
| 121 | + } | |
| 122 | + else if (lineix == 4) | |
| 123 | + { | |
| 124 | + ColorConsole.Write($"Pool:"); | |
| 125 | + ColorConsole.Write($"{wa.Xml_PoolName}", ConsoleColor.Cyan); | |
| 126 | + var fc1 = wa.PoolState == null ? ConsoleColor.Red | |
| 127 | + : wa.PoolState.Contains("Started") ? ConsoleColor.Green | |
| 128 | + : wa.PoolState.Contains("Unregistered") ? ConsoleColor.Red | |
| 129 | + : ConsoleColor.Yellow; | |
| 130 | + string waps = wa.PoolState == null ? "Unregistered/Unknown" : wa.PoolState; | |
| 131 | + ColorConsole.Write($"{waps}", fc1, bracket: "()"); | |
| 132 | + ColorConsole.Write($", identity:"); | |
| 133 | + ColorConsole.WriteLine($"{wa.PoolAccount}", ConsoleColor.White); | |
| 134 | + } | |
| 135 | + else if (lineix==5) | |
| 136 | + { | |
| 137 | + ColorConsole.WriteLine(); | |
| 138 | + } | |
| 139 | + else | |
| 140 | + { | |
| 141 | + return null; | |
| 142 | + } | |
| 143 | + return ""; | |
| 144 | + } | |
| 145 | + #endregion private method: DisplayWebAppInfo | |
| 146 | + #region | |
| 147 | + private static object Restart(object dobj, object parameters) | |
| 148 | + { | |
| 149 | + WebApplication d = dobj as WebApplication; | |
| 150 | + using (ServerManager sm = new ServerManager()) | |
| 151 | + { | |
| 152 | + try { WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName)?.Stop(); } catch { Console.WriteLine($"Pool {d.Xml_PoolName} already stopped."); } | |
| 153 | + try { WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName)?.Stop(); } catch { Console.WriteLine($"Site {d.Xml_SiteName} already stopped."); } | |
| 154 | + | |
| 155 | + SiteStart(d, parameters); | |
| 156 | + PoolStart(d, parameters); | |
| 157 | + PoolRecycle(d, parameters); | |
| 158 | + | |
| 159 | + Console.WriteLine($"Pool {d.Xml_PoolName} and site {d.Xml_SiteName} restarted."); | |
| 160 | + return parameters; | |
| 161 | + } | |
| 162 | + } | |
| 163 | + private | |
| 164 | + static object PoolStart(object dobj, object parameters) | |
| 165 | + { | |
| 166 | + WebApplication d = dobj as WebApplication; | |
| 167 | + using (ServerManager sm = new ServerManager()) | |
| 168 | + { | |
| 169 | + bool success = false; | |
| 170 | + for (var i = 1; i <= 10; i++) | |
| 171 | + { | |
| 172 | + var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); | |
| 173 | + if (p != null && p.State == ObjectState.Stopped) { p.Start(); success = true; break; } | |
| 174 | + else | |
| 175 | + { | |
| 176 | + Console.WriteLine($"Trying to start pool {d.Xml_PoolName} ... Press key 'X' to exit..."); | |
| 177 | + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } | |
| 178 | + | |
| 179 | + Thread.Sleep(1000); | |
| 180 | + } | |
| 181 | + } | |
| 182 | + var successstr = success ? "started" : "NOT started"; | |
| 183 | + Console.WriteLine($"{d.Xml_PoolName} {successstr}."); | |
| 184 | + return parameters; | |
| 185 | + } | |
| 186 | + } | |
| 187 | + private static object PoolRecycle(object dobj, object parameters) | |
| 188 | + { | |
| 189 | + WebApplication d = dobj as WebApplication; | |
| 190 | + using (ServerManager sm = new ServerManager()) | |
| 191 | + { | |
| 192 | + bool success = false; | |
| 193 | + for (var i = 1; i < 4; i++) | |
| 194 | + { | |
| 195 | + var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); | |
| 196 | + if (p != null && p.State == ObjectState.Started) { p.Recycle(); success = true; break; } | |
| 197 | + else | |
| 198 | + { | |
| 199 | + Console.WriteLine($"Trying to recycle pool {d.Xml_PoolName} ... Press key 'X' to exit..."); | |
| 200 | + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } | |
| 201 | + Thread.Sleep(1000); | |
| 202 | + } | |
| 203 | + } | |
| 204 | + var successstr = success ? "recycled" : "NOT recycled"; | |
| 205 | + Console.WriteLine($"{d.Xml_PoolName} {successstr}."); | |
| 206 | + return parameters; | |
| 207 | + } | |
| 208 | + } | |
| 209 | + private static object PoolStop(object dobj, object parameters) | |
| 210 | + { | |
| 211 | + using (ServerManager sm = new ServerManager()) | |
| 212 | + { | |
| 213 | + WebApplication d = dobj as WebApplication; | |
| 214 | + bool success = false; | |
| 215 | + for (var i = 1; i <= 10; i++) | |
| 216 | + { | |
| 217 | + var p = WebApplicationManagerCore.GetPool(sm, d.Xml_PoolName); | |
| 218 | + if (p != null && p.State == ObjectState.Started) { p.Stop(); success = true; break; } | |
| 219 | + else | |
| 220 | + { | |
| 221 | + Console.WriteLine($"Trying to stop pool {d.Xml_PoolName} ... Press key 'X' to exit..."); | |
| 222 | + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } | |
| 223 | + | |
| 224 | + Thread.Sleep(1000); | |
| 225 | + } | |
| 226 | + } | |
| 227 | + var successstr = success ? "stopped" : "NOT stopped"; | |
| 228 | + Console.WriteLine($"{d.Xml_PoolName} {successstr}."); | |
| 229 | + return parameters; | |
| 230 | + } | |
| 231 | + } | |
| 232 | + private static object SiteStart(object dobj, object parameters) | |
| 233 | + { | |
| 234 | + WebApplication d = dobj as WebApplication; | |
| 235 | + using (ServerManager sm = new ServerManager()) | |
| 236 | + { | |
| 237 | + bool success = false; | |
| 238 | + for (var i = 1; i < 4; i++) | |
| 239 | + { | |
| 240 | + var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); | |
| 241 | + if (s != null && s.State == ObjectState.Stopped) { s.Start(); success = true; break; } | |
| 242 | + else | |
| 243 | + { | |
| 244 | + Console.WriteLine($"Trying to start site {d.Xml_SiteName} ... Press key 'X' to exit..."); | |
| 245 | + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } | |
| 246 | + Thread.Sleep(1000); | |
| 247 | + } | |
| 248 | + } | |
| 249 | + var successstr = success ? "started" : "NOT started"; | |
| 250 | + Console.WriteLine($"{d.Xml_SiteName} {successstr}."); | |
| 251 | + return parameters; | |
| 252 | + } | |
| 253 | + } | |
| 254 | + private static object SiteStop(object dobj, object parameters) | |
| 255 | + { | |
| 256 | + WebApplication d = dobj as WebApplication; | |
| 257 | + using (ServerManager sm = new ServerManager()) | |
| 258 | + { | |
| 259 | + bool success = false; | |
| 260 | + for (var i = 1; i < 4; i++) | |
| 261 | + { | |
| 262 | + var s = WebApplicationManagerCore.GetSite(sm, d.Xml_SiteName); | |
| 263 | + if (s != null && s.State == ObjectState.Started) { s.Stop(); success = true; break; } | |
| 264 | + else | |
| 265 | + { | |
| 266 | + Console.WriteLine($"Trying to stop site {d.Xml_SiteName} ... Press key 'X' to exit..."); | |
| 267 | + if (Console.KeyAvailable) { if (Console.ReadKey().KeyChar.ToString().ToUpper() == "X") { break; } } | |
| 268 | + Thread.Sleep(1000); | |
| 269 | + } | |
| 270 | + } | |
| 271 | + var successstr = success ? "stopped" : "NOT stopped"; | |
| 272 | + Console.WriteLine($"{d.Xml_SiteName} {successstr}."); | |
| 273 | + return parameters; | |
| 274 | + } | |
| 275 | + } | |
| 276 | + private static object Register(object dobj, object parameters) | |
| 277 | + { | |
| 278 | + WebApplication d = dobj as WebApplication; | |
| 279 | + WebApplicationManagerCore.RegisterWebApplication(d.Xml_SiteName, d.Xml_PoolName, d.Xml_AppName, d.Xml_AppPhysicalPath, d.Xml_SitePhysicalPath, 8080, d.Xml_RecreatePool, d.Xml_RecreateSite, d.Xml_RecreateApp, d.Xml_PoolPipeLineMode); | |
| 280 | + Console.WriteLine($"{d.Xml_AppName} is registered in site {d.Xml_SiteName} using pool {d.Xml_PoolName}."); | |
| 281 | + return parameters; | |
| 282 | + } | |
| 283 | + private static object Unregister(object dobj, object parameters) | |
| 284 | + { | |
| 285 | + WebApplication d = dobj as WebApplication; | |
| 286 | + WebApplicationManagerCore.UnRegisterWebApplication(d.Xml_AppName, d.Xml_PoolName, d.Xml_SiteName, d.Xml_ForceRemovePool, d.Xml_ForceRemoveSite); | |
| 287 | + Console.WriteLine($"{d.Xml_AppName} is unregistered from site {d.Xml_SiteName} and from pool {d.Xml_PoolName}."); | |
| 288 | + return parameters; | |
| 289 | + } | |
| 290 | + private static object SetImpersonateIdentity(object dobj, object parameters) | |
| 291 | + { | |
| 292 | + WebApplication d = dobj as WebApplication; | |
| 293 | + string username="", password = "",impersonate="FALSE"; | |
| 294 | + bool parametersarealreadyset = parameters != null; | |
| 295 | + string olduserinfo = WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile); | |
| 296 | + if (parametersarealreadyset) | |
| 297 | + { | |
| 298 | + impersonate = ((Dictionary<string, string>)parameters)["impersonate"]; | |
| 299 | + username = ((Dictionary<string, string>)parameters)["username"]; | |
| 300 | + password = ((Dictionary<string, string>)parameters)["password"]; | |
| 301 | + } | |
| 302 | + else | |
| 303 | + { | |
| 304 | + while(true) | |
| 305 | + { | |
| 306 | + | |
| 307 | + Console.WriteLine($"Current user info: {olduserinfo}"); | |
| 308 | + Console.WriteLine("Set impersonate-on status (true/false), then [Enter], EX=exit."); | |
| 309 | + impersonate = Console.ReadLine().ToUpper(); | |
| 310 | + if (impersonate == "EX") { return null; } | |
| 311 | + else if (impersonate == "FALSE") { break; } | |
| 312 | + else if (impersonate == "TRUE") | |
| 313 | + { | |
| 314 | + Console.WriteLine("Enter username, then [Enter]."); | |
| 315 | + var un = !string.IsNullOrWhiteSpace(d.Xml_PoolUsername) ? $"empty={d.Xml_PoolUsername }," : ""; | |
| 316 | + Console.WriteLine($"{un}EX=exit"); | |
| 317 | + username = Console.ReadLine().ToUpper(); | |
| 318 | + if (impersonate == "EX") { return null; } | |
| 319 | + Console.WriteLine("Enter password, then [Enter]"); | |
| 320 | + var pw = !string.IsNullOrWhiteSpace(d.Xml_PoolPassword) ? $"empty={d.Xml_PoolPassword}," : ""; | |
| 321 | + Console.WriteLine($"{pw}EX=exit"); | |
| 322 | + password = Console.ReadLine().ToUpper(); | |
| 323 | + if (impersonate == "EX") { return null; } | |
| 324 | + break; | |
| 325 | + //bool valid = System.Web.ApplicationSerices.AuthenticationService.ValidateUser(username, password, mull); | |
| 326 | + } | |
| 327 | + else | |
| 328 | + { | |
| 329 | + Menu.IncorrectSelection(); | |
| 330 | + continue; | |
| 331 | + } | |
| 332 | + } | |
| 333 | + parameters = new Dictionary<string, string> { { "impersonate", impersonate }, { "username", username }, { "password", password }, }; | |
| 334 | + } | |
| 335 | + WebApplicationManagerCore.SetImpersonateIdentity(d.Xml_IdentityConfigFile, impersonate, username, password); | |
| 336 | + Console.WriteLine($"Impersonate identity changed for webapp {d.Xml_AppName}."); | |
| 337 | + Console.WriteLine($"From '{olduserinfo}' to '{WebApplicationManagerCore.GetImpersonateIdentityInfo(d.Xml_IdentityConfigFile)}'"); | |
| 338 | + | |
| 339 | + return parameters; | |
| 340 | + } | |
| 341 | + private static object PoolSetUserAccount(object dobj, object parameters) | |
| 342 | + { | |
| 343 | + WebApplication d = dobj as WebApplication; | |
| 344 | + string username, password = ""; | |
| 345 | + bool parametersarealreadyset = parameters != null; | |
| 346 | + string olduserinfo = WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName); | |
| 347 | + if (parametersarealreadyset) | |
| 348 | + { | |
| 349 | + username = ((Dictionary<string, string>)parameters)["username"]; | |
| 350 | + password = ((Dictionary<string, string>)parameters)["password"]; | |
| 351 | + } | |
| 352 | + else | |
| 353 | + { | |
| 354 | + Console.WriteLine($"Current user info: {olduserinfo}"); | |
| 355 | + Console.WriteLine("Enter username, then [Enter]."); | |
| 356 | + Console.WriteLine("Special usernames are: (Empty=API) "); | |
| 357 | + Console.WriteLine($" (API) {nameof(ProcessModelIdentityType.ApplicationPoolIdentity)}"); | |
| 358 | + Console.WriteLine($" (LSE) {nameof(ProcessModelIdentityType.LocalService)}"); | |
| 359 | + Console.WriteLine($" (LSY) {nameof(ProcessModelIdentityType.LocalSystem)}"); | |
| 360 | + Console.WriteLine($" (NSE) {nameof(ProcessModelIdentityType.NetworkService)}"); | |
| 361 | + ColorConsole.WriteLine(); | |
| 362 | + ColorConsole.Write(" (EX) ", ConsoleColor.Red); ColorConsole.WriteLine("Exit"); | |
| 363 | + username = Console.ReadLine().ToUpper(); | |
| 364 | + if (username == "EX") { return null; } | |
| 365 | + if (string.IsNullOrEmpty(username)) { username = nameof(ProcessModelIdentityType.ApplicationPoolIdentity); }; | |
| 366 | + if (username == "API" || username == nameof(ProcessModelIdentityType.ApplicationPoolIdentity)) { username = nameof(ProcessModelIdentityType.ApplicationPoolIdentity); } | |
| 367 | + else if (username == "LSE" || username == nameof(ProcessModelIdentityType.LocalService)) { username = nameof(ProcessModelIdentityType.LocalService); } | |
| 368 | + else if (username == "LSY" || username == nameof(ProcessModelIdentityType.LocalSystem)) { username = nameof(ProcessModelIdentityType.LocalSystem); } | |
| 369 | + else if (username == "NSE" || username == nameof(ProcessModelIdentityType.NetworkService)) { username = nameof(ProcessModelIdentityType.NetworkService); } | |
| 370 | + else | |
| 371 | + { | |
| 372 | + Console.WriteLine("Enter password, then [Enter]"); | |
| 373 | + password = Console.ReadLine().ToUpper(); | |
| 374 | + //bool valid = System.Web.ApplicationSerices.AuthenticationService.ValidateUser(username, password, mull); | |
| 375 | + } | |
| 376 | + parameters = new Dictionary<string, string> { { "username", username }, { "password", password }, }; | |
| 377 | + } | |
| 378 | + WebApplicationManagerCore.SetPoolUserAccount(d.Xml_AppName, d.Xml_SiteName, username, password); | |
| 379 | + Console.WriteLine($"Pool user changed from {olduserinfo} to {WebApplicationManagerCore.GetUserInfo(d.Xml_PoolName)} for pool {d.Xml_PoolName}."); | |
| 380 | + return parameters; | |
| 381 | + } | |
| 382 | + #endregion | |
| 383 | + } | |
| 384 | + | |
| 385 | + public static class WebApplicationManagerCore | |
| 386 | + { | |
| 387 | + #region private method: CollectWebAppInfo | |
| 388 | + public static WebApplication CollectWebAppInfo(SiteCollection sites,ApplicationPoolCollection pools, WebApplication wadef) | |
| 389 | + { | |
| 390 | + var wa = new WebApplication(wadef); | |
| 391 | + try | |
| 392 | + { | |
| 393 | + wa.Site = sites[wa.Xml_SiteName]; | |
| 394 | + if (wa.Site == null) { throw new Exception(); } | |
| 395 | + else | |
| 396 | + { | |
| 397 | + var ss = wa.Site.State; | |
| 398 | + wa.SiteState = ss.ToString(); | |
| 399 | + wa.SitePortList = ""; | |
| 400 | + foreach (var binding in wa.Site.Bindings) | |
| 401 | + { | |
| 402 | + if (binding?.EndPoint?.Port != null) { wa.SitePortList += $"[{binding.EndPoint.Port}]"; } | |
| 403 | + } | |
| 404 | + var wn = Path.Combine("/", wa.Xml_AppName); | |
| 405 | + var _wa = wa.Site.Applications[wn]; | |
| 406 | + if (_wa == null) | |
| 407 | + { | |
| 408 | + wa.ApplicationState = "Unregistered/Unknown"; | |
| 409 | + wa.ApplicationPath = ""; | |
| 410 | + wa.Application = null; | |
| 411 | + wa.AppImpersonateIdentity = ""; | |
| 412 | + } | |
| 413 | + else | |
| 414 | + { | |
| 415 | + wa.ApplicationState = "Registered"; | |
| 416 | + wa.ApplicationPath = _wa.Path; | |
| 417 | + wa.Application = _wa; | |
| 418 | + wa.AppImpersonateIdentity = GetImpersonateIdentityInfo(wa.Xml_IdentityConfigFile); | |
| 419 | + } | |
| 420 | + } | |
| 421 | + } | |
| 422 | + catch (Exception ex) | |
| 423 | + { | |
| 424 | + wa.Site = null; | |
| 425 | + wa.SiteState = "Unregistered/Unknown"; | |
| 426 | + wa.SitePortList = ""; | |
| 427 | + wa.Application = null; | |
| 428 | + wa.ApplicationState = "Unregistered/Unknown"; | |
| 429 | + wa.ApplicationPath = ""; | |
| 430 | + }; | |
| 431 | + try | |
| 432 | + { | |
| 433 | + wa.ApplicationPool = pools[wa.Xml_PoolName]; | |
| 434 | + if (wa.ApplicationPool == null) { throw new Exception(); } | |
| 435 | + else | |
| 436 | + { | |
| 437 | + wa.PoolState = wa.ApplicationPool.State.ToString(); | |
| 438 | + string pa = $"{wa.ApplicationPool.ProcessModel.IdentityType}"; | |
| 439 | + if (wa.ApplicationPool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) | |
| 440 | + { | |
| 441 | + pa += $"({wa.ApplicationPool.ProcessModel.UserName}[{wa.ApplicationPool.ProcessModel.Password}])"; | |
| 442 | + } | |
| 443 | + wa.PoolAccount = pa; | |
| 444 | + } | |
| 445 | + } | |
| 446 | + catch | |
| 447 | + { | |
| 448 | + wa.ApplicationPool = null; | |
| 449 | + wa.PoolState = "Unregistered/Unknown"; | |
| 450 | + wa.PoolAccount = ""; | |
| 451 | + } | |
| 452 | + return wa; | |
| 453 | + } | |
| 454 | + #endregion private method: CollectWebAppInfo | |
| 455 | + | |
| 456 | + #region private method:RegisterWebApplication | |
| 457 | + public static void RegisterWebApplication(string sitename, string poolname, string appname, string poolphypath, string sitephypath, int siteport, bool recreatepool, bool recreatesite, bool recreateapp,ManagedPipelineMode plmode) | |
| 458 | + { | |
| 459 | + using (ServerManager serverManager = new ServerManager()) | |
| 460 | + { | |
| 461 | + if (!isExistWebAppPool(serverManager, poolname)) { CreateWebAppPool(serverManager, poolname, plmode); } | |
| 462 | + else if (recreatepool) { RemoveWebAppPool(serverManager, poolname); CreateWebAppPool(serverManager, poolname, plmode); } | |
| 463 | + | |
| 464 | + if (!isExistWebSite(serverManager, sitename)) { CreateWebSite(serverManager, sitename, poolname, sitename, sitephypath, siteport); } | |
| 465 | + else if (recreatesite) { RemoveWebSite(serverManager, sitename); CreateWebSite(serverManager, sitename, poolname, sitename, sitephypath, siteport);} | |
| 466 | + | |
| 467 | + SetItemProperty(serverManager, poolname, "managedRuntimeVersion", "v4.0"); | |
| 468 | + SetItemProperty(serverManager, poolname, "enable32BitAppOnWin64", "true"); | |
| 469 | + | |
| 470 | + if (!isExistWebApp(serverManager, sitename, appname)) { CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); } | |
| 471 | + else if (recreateapp) { RemoveWebApp(serverManager, appname, sitename); CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); } | |
| 472 | + | |
| 473 | + CommitChanges(serverManager, poolname); | |
| 474 | + } | |
| 475 | + } | |
| 476 | + #endregion private method:RegisterWebApplication | |
| 477 | + #region private method:UnRegisterWebApplication | |
| 478 | + public static void UnRegisterWebApplication(string appname, string poolname, string sitename = "Default Web Site",bool forceremovepool=false, bool forceremovesite = false) | |
| 479 | + { | |
| 480 | + using (ServerManager sm = new ServerManager()) | |
| 481 | + { | |
| 482 | + if (isExistWebApp(sm, sitename, appname)) { RemoveWebApp(sm, appname, sitename); } | |
| 483 | + if (isExistWebAppPool(sm,poolname) && forceremovepool) { RemoveWebAppPool(sm,poolname); } | |
| 484 | + if (isExistWebSite(sm, sitename) && forceremovesite) { RemoveWebSite(sm, poolname); } | |
| 485 | + CommitChanges(sm, poolname); | |
| 486 | + } | |
| 487 | + } | |
| 488 | + #endregion private method:UnRegisterWebApplication | |
| 489 | + #region private method:SetImpersonateIdentity | |
| 490 | + public static void SetImpersonateIdentity(string filepath, string impersonate, string username, string password) | |
| 491 | + { | |
| 492 | + var identityxml = new XElement("identity"); | |
| 493 | + identityxml.Add(new XAttribute("impersonate", impersonate.ToLower())); | |
| 494 | + if (impersonate.ToLower() == "true") | |
| 495 | + { | |
| 496 | + if (!string.IsNullOrWhiteSpace(username)) | |
| 497 | + { | |
| 498 | + identityxml.Add(new XAttribute("userName", username)); | |
| 499 | + identityxml.Add(new XAttribute("password", string.IsNullOrWhiteSpace(password)?"":password)); | |
| 500 | + } | |
| 501 | + } | |
| 502 | + identityxml.Save(filepath); | |
| 503 | + } | |
| 504 | + #endregion private method:SetImpersonateIdentity | |
| 505 | + #region private method:SetPoolUserAccount | |
| 506 | + public static void SetPoolUserAccount(string appname, string sitename, string username, string password) | |
| 507 | + { | |
| 508 | + using (var sm = new ServerManager()) | |
| 509 | + { | |
| 510 | + //var pool = GetPool(GetPoolName(sitename, appname)); | |
| 511 | + var pool = GetPool(sm, sitename, appname); | |
| 512 | + if (username == nameof(ProcessModelIdentityType.ApplicationPoolIdentity) | |
| 513 | + || username == nameof(ProcessModelIdentityType.LocalService) | |
| 514 | + || username == nameof(ProcessModelIdentityType.LocalSystem) | |
| 515 | + || username == nameof(ProcessModelIdentityType.NetworkService)) | |
| 516 | + { | |
| 517 | + pool.ProcessModel.UserName = null; | |
| 518 | + pool.ProcessModel.Password = null; | |
| 519 | + pool.ProcessModel.IdentityType = (ProcessModelIdentityType)Enum.Parse(typeof(ProcessModelIdentityType), username); | |
| 520 | + } | |
| 521 | + else // if (ProcessModelIdentityType.SpecificUser) | |
| 522 | + { | |
| 523 | + pool.ProcessModel.UserName = username; | |
| 524 | + pool.ProcessModel.Password = password; | |
| 525 | + pool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser; | |
| 526 | + } | |
| 527 | + CommitChanges(sm, pool.Name); | |
| 528 | + } | |
| 529 | + } | |
| 530 | + #endregion private method:SetPoolUserAccount | |
| 531 | + #region private method:CommitChanges | |
| 532 | + private static void CommitChanges(ServerManager serverManager, string poolname) | |
| 533 | + { | |
| 534 | + serverManager.CommitChanges(); | |
| 535 | + if (isExistWebAppPool(poolname)) | |
| 536 | + { | |
| 537 | + var p = GetPool(serverManager, poolname); | |
| 538 | + if (p.State == ObjectState.Started) { p.Recycle(); } | |
| 539 | + } | |
| 540 | + } | |
| 541 | + #endregion private method:CommitChanges | |
| 542 | + | |
| 543 | + #region private methods: Get information (with no ServerManager parameter) | |
| 544 | + public static string GetImpersonateIdentityInfo(string filepath) | |
| 545 | + { | |
| 546 | + try | |
| 547 | + { | |
| 548 | + var xml = XElement.Load(filepath); | |
| 549 | + var identityXml = xml; //?.Element(XName.Get("identity")); | |
| 550 | + if (identityXml == null) { return "no info"; } | |
| 551 | + else | |
| 552 | + { | |
| 553 | + var impersonate = identityXml.Attribute(XName.Get("impersonate"))?.Value; | |
| 554 | + var username = identityXml.Attribute(XName.Get("userName"))?.Value; | |
| 555 | + var password = identityXml.Attribute(XName.Get("password"))?.Value; | |
| 556 | + string unpswinfo = $", username[password]: {username}[{password}]"; | |
| 557 | + var userinfo = impersonate.ToLower() == "true" && !string.IsNullOrWhiteSpace(username) ? unpswinfo : ""; | |
| 558 | + var retinfo = $"Impersonate={impersonate}{userinfo}"; | |
| 559 | + return retinfo; | |
| 560 | + } | |
| 561 | + } | |
| 562 | + catch { return "no info (exception)"; } | |
| 563 | + } | |
| 564 | + public static string GetUserInfo(string poolname) | |
| 565 | + { | |
| 566 | + using (var sm2 = new ServerManager()) | |
| 567 | + { | |
| 568 | + var pool = sm2.ApplicationPools[poolname]; | |
| 569 | + string userinfo = ""; | |
| 570 | + if (pool != null) | |
| 571 | + { | |
| 572 | + if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) | |
| 573 | + { | |
| 574 | + userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; | |
| 575 | + } | |
| 576 | + else | |
| 577 | + { | |
| 578 | + userinfo = $"{pool.ProcessModel.IdentityType}"; | |
| 579 | + } | |
| 580 | + } | |
| 581 | + return userinfo; | |
| 582 | + } | |
| 583 | + } | |
| 584 | + private static string GetPoolName(string sitename,string appname) | |
| 585 | + { | |
| 586 | + using (ServerManager serverManager = new ServerManager()) | |
| 587 | + { | |
| 588 | + return GetPoolName(serverManager, sitename, appname); | |
| 589 | + } | |
| 590 | + } | |
| 591 | + public static ApplicationPool GetPool(string sitename, string appname) | |
| 592 | + { | |
| 593 | + using (ServerManager serverManager = new ServerManager()) | |
| 594 | + { | |
| 595 | + return GetPool(serverManager, sitename, appname); | |
| 596 | + } | |
| 597 | + } | |
| 598 | + public static ApplicationPool GetPool(string poolname) | |
| 599 | + { | |
| 600 | + using (ServerManager serverManager = new ServerManager()) | |
| 601 | + { | |
| 602 | + return GetPool(serverManager,poolname); | |
| 603 | + } | |
| 604 | + } | |
| 605 | + private static bool isExistWebAppPool(string poolname) | |
| 606 | + { | |
| 607 | + using (ServerManager serverManager = new ServerManager()) | |
| 608 | + { | |
| 609 | + return isExistWebAppPool(serverManager, poolname); | |
| 610 | + } | |
| 611 | + } | |
| 612 | + private static bool isExistWebApp(string sitename,string appname) | |
| 613 | + { | |
| 614 | + using (ServerManager serverManager = new ServerManager()) | |
| 615 | + { | |
| 616 | + return isExistWebApp(serverManager ,sitename, appname); | |
| 617 | + } | |
| 618 | + } | |
| 619 | + private static bool isExistWebSite(string sitename) | |
| 620 | + { | |
| 621 | + using (ServerManager serverManager = new ServerManager()) | |
| 622 | + { | |
| 623 | + return isExistWebSite(serverManager ,sitename); | |
| 624 | + } | |
| 625 | + } | |
| 626 | + #endregion private methods: Get information (with no ServerManager parameter) | |
| 627 | + #region private methods: Get information | |
| 628 | + public static string GetUserInfo(ServerManager sm, string poolname) | |
| 629 | + { | |
| 630 | + var pool = sm.ApplicationPools[poolname]; | |
| 631 | + string userinfo = ""; | |
| 632 | + if (pool != null) | |
| 633 | + { | |
| 634 | + if (pool.ProcessModel.IdentityType == ProcessModelIdentityType.SpecificUser) | |
| 635 | + { | |
| 636 | + userinfo = $"{pool.ProcessModel.UserName}({pool.ProcessModel.Password})"; | |
| 637 | + } | |
| 638 | + else | |
| 639 | + { | |
| 640 | + userinfo = $"{pool.ProcessModel.IdentityType}"; | |
| 641 | + } | |
| 642 | + } | |
| 643 | + return userinfo; | |
| 644 | + } | |
| 645 | + public static string GetPoolName(ServerManager serverManager,string sitename, string appname) | |
| 646 | + { | |
| 647 | + Site site = serverManager.Sites[sitename]; | |
| 648 | + Application application = site.Applications[Path.Combine("/", appname)]; | |
| 649 | + return application.ApplicationPoolName; | |
| 650 | + } | |
| 651 | + public static ApplicationPool GetPool(ServerManager serverManager, string sitename, string appname) | |
| 652 | + { | |
| 653 | + Site site = serverManager.Sites[sitename]; | |
| 654 | + Application application = site.Applications[Path.Combine("/",appname)]; | |
| 655 | + return serverManager.ApplicationPools[application.ApplicationPoolName]; | |
| 656 | + } | |
| 657 | + public static ApplicationPool GetPool(ServerManager serverManager, string poolname) | |
| 658 | + { | |
| 659 | + return serverManager.ApplicationPools[poolname]; | |
| 660 | + } | |
| 661 | + public static Site GetSite(ServerManager serverManager, string sitename) | |
| 662 | + { | |
| 663 | + return serverManager.Sites[sitename]; | |
| 664 | + } | |
| 665 | + private static bool isExistWebAppPool(ServerManager serverManager, string poolname) | |
| 666 | + { | |
| 667 | + try | |
| 668 | + { | |
| 669 | + var p = serverManager.ApplicationPools[poolname]; | |
| 670 | + if (p == null) { return false; } | |
| 671 | + return p.State != ObjectState.Unknown; | |
| 672 | + } | |
| 673 | + catch { return false; } | |
| 674 | + } | |
| 675 | + private static bool isExistWebApp(ServerManager serverManager, string sitename, string appname) | |
| 676 | + { | |
| 677 | + try | |
| 678 | + { | |
| 679 | + var an = Path.Combine(@"/",appname); | |
| 680 | + var app = serverManager.Sites[sitename].Applications[an]; | |
| 681 | + return app != null; | |
| 682 | + } | |
| 683 | + catch { return false; } | |
| 684 | + } | |
| 685 | + private static bool isExistWebSite(ServerManager serverManager, string sitename) | |
| 686 | + { | |
| 687 | + try | |
| 688 | + { | |
| 689 | + var s = serverManager.Sites[sitename]; | |
| 690 | + if (s == null) { return false; } | |
| 691 | + return s.State != ObjectState.Unknown; | |
| 692 | + } | |
| 693 | + catch { return false; } | |
| 694 | + } | |
| 695 | + #endregion private methods: Get information | |
| 696 | + #region private methods: Set information | |
| 697 | + private static void SetItemProperty(ServerManager serverManager, string poolname, string propertyname, string propertyvalue) | |
| 698 | + { | |
| 699 | + var pool = GetPool(serverManager, poolname); | |
| 700 | + pool.SetAttributeValue(propertyname, propertyvalue); //????????????????????????? | |
| 701 | + } | |
| 702 | + private static void CreateWebAppPool(ServerManager serverManager ,string poolname, ManagedPipelineMode plmode) | |
| 703 | + { | |
| 704 | + serverManager.ApplicationPools.Add(poolname); | |
| 705 | + ApplicationPool pool = serverManager.ApplicationPools[poolname]; | |
| 706 | + pool.ManagedPipelineMode = plmode; | |
| 707 | + } | |
| 708 | + private static void CreateWebApp(ServerManager serverManager, string appname, string poolname, string sitename, string poolphypath) | |
| 709 | + { | |
| 710 | + Site site = serverManager.Sites[sitename]; | |
| 711 | + Application application = site.Applications[Path.Combine("/",appname)]; | |
| 712 | + if (application != null) { site.Applications.Remove(application); } | |
| 713 | + application = site.Applications.Add(Path.Combine("/",appname), poolphypath); | |
| 714 | + application.ApplicationPoolName = poolname; | |
| 715 | + } | |
| 716 | + private static void CreateWebSite(ServerManager serverManager, string sitename, string poolname, string hostheader, string sitephypath, int siteport = 8000) | |
| 717 | + { | |
| 718 | + Site mySite = serverManager.Sites.Add(sitename, sitephypath, siteport); | |
| 719 | + mySite.Applications[0].ApplicationPoolName = poolname; | |
| 720 | + //mysite.Applications[0].VirtualDirectories[0].PhysicalPath = sitephypath; | |
| 721 | + mySite.ServerAutoStart = true; | |
| 722 | + } | |
| 723 | + private static void RemoveWebSite(ServerManager serverManager, string sitename) | |
| 724 | + { | |
| 725 | + Site mySite = serverManager.Sites[sitename]; | |
| 726 | + if (mySite != null) { serverManager.Sites.Remove(mySite); } | |
| 727 | + } | |
| 728 | + private static void RemoveWebAppPool(ServerManager serverManager,string poolname) | |
| 729 | + { | |
| 730 | + try | |
| 731 | + { | |
| 732 | + ApplicationPool pool = serverManager.ApplicationPools[poolname]; | |
| 733 | + serverManager.ApplicationPools.Remove(pool); | |
| 734 | + } | |
| 735 | + catch { } | |
| 736 | + } | |
| 737 | + private static void RemoveWebApp(ServerManager serverManager, string appname, string sitename) | |
| 738 | + { | |
| 739 | + Site site = serverManager.Sites[sitename]; | |
| 740 | + Application application = site.Applications[Path.Combine("/",appname)]; | |
| 741 | + site.Applications.Remove(application); | |
| 742 | + } | |
| 743 | + #endregion private methods: Set information (wit no ServerManager parameter) | |
| 744 | + #region private methods: Set information (with no ServerManager parameter) | |
| 745 | + private static void SetItemProperty(string poolname, string propertyname, string propertyvalue) | |
| 746 | + { | |
| 747 | + using (ServerManager serverManager = new ServerManager()) | |
| 748 | + { | |
| 749 | + SetItemProperty(serverManager, poolname, propertyname, propertyvalue); | |
| 750 | + CommitChanges(serverManager, poolname); | |
| 751 | + } | |
| 752 | + } | |
| 753 | + private static void CreateWebAppPool(string poolname, ManagedPipelineMode plmode) | |
| 754 | + { | |
| 755 | + using (ServerManager serverManager = new ServerManager()) | |
| 756 | + { | |
| 757 | + CreateWebAppPool(serverManager, poolname, plmode); | |
| 758 | + CommitChanges(serverManager, poolname); | |
| 759 | + } | |
| 760 | + } | |
| 761 | + private static void CreateWebApp(string appname, string poolname, string sitename, string poolphypath) | |
| 762 | + { | |
| 763 | + using (ServerManager serverManager = new ServerManager()) | |
| 764 | + { | |
| 765 | + CreateWebApp(serverManager, appname, poolname, sitename, poolphypath); | |
| 766 | + CommitChanges(serverManager, poolname); | |
| 767 | + } | |
| 768 | + } | |
| 769 | + private static void CreateWebSite(string sitename, string poolname, string hostheader, string sitephypath, int siteport = 8000) | |
| 770 | + { | |
| 771 | + using (ServerManager serverManager = new ServerManager()) | |
| 772 | + { | |
| 773 | + CreateWebSite(serverManager, sitename, poolname, hostheader, sitephypath, siteport); | |
| 774 | + CommitChanges(serverManager, poolname); | |
| 775 | + } | |
| 776 | + } | |
| 777 | + private static void RemoveWebSite(string sitename) | |
| 778 | + { | |
| 779 | + using (ServerManager serverManager = new ServerManager()) { RemoveWebSite(serverManager, sitename); } | |
| 780 | + } | |
| 781 | + private static void RemovePool(string poolname) | |
| 782 | + { | |
| 783 | + using (ServerManager sm = new ServerManager()) | |
| 784 | + { | |
| 785 | + RemoveWebAppPool(sm, poolname); | |
| 786 | + CommitChanges(sm, poolname); | |
| 787 | + } | |
| 788 | + } | |
| 789 | + private static void RemoveWebApp(string sitename, string appname) | |
| 790 | + { | |
| 791 | + using (ServerManager sm = new ServerManager()) | |
| 792 | + { | |
| 793 | + RemoveWebApp(sm, appname, sitename); | |
| 794 | + CommitChanges(sm, GetPoolName(sm,sitename, appname)); | |
| 795 | + } | |
| 796 | + } | |
| 797 | + #endregion private methods: Set information (with no ServerManager parameter) | |
| 798 | + | |
| 799 | + } | |
| 800 | + #region WebApplicationManagerXmlProcessor class | |
| 801 | + public class WebApplicationManagerXmlProcessor : XmlParser | |
| 802 | + { | |
| 803 | + #region constructor | |
| 804 | + public WebApplicationManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) | |
| 805 | + { | |
| 806 | + _webapplist = new List<WebApplication>(); | |
| 807 | + var waxmllist = GetAllXElements(nameof(WebApplication.XmlStructure.WebApplication)); | |
| 808 | + if (waxmllist != null && waxmllist.Any()) | |
| 809 | + { | |
| 810 | + foreach (var waxml in waxmllist) { _webapplist.Add(new WebApplication(waxml)); } | |
| 811 | + } | |
| 812 | + } | |
| 813 | + #endregion constructor | |
| 814 | + #region properties | |
| 815 | + List<WebApplication> _webapplist = null; | |
| 816 | + #endregion properties | |
| 817 | + | |
| 818 | + #region GetDefinitionList | |
| 819 | + public List<WebApplication> GetDefinitionList() { return _webapplist; } | |
| 820 | + #endregion GetDefinitionList | |
| 821 | + } | |
| 822 | + #endregion WebApplicationManagerXmlProcessor class | |
| 823 | + #region WebApplication class | |
| 824 | + public class WebApplication : XmlLinqBase | |
| 825 | + { | |
| 826 | + #region properties from Xml definition | |
| 827 | + public string Xml_AppName; | |
| 828 | + public string Xml_Description; | |
| 829 | + public string Xml_PoolName; | |
| 830 | + public string Xml_SiteName; | |
| 831 | + public string Xml_AppPhysicalPath; | |
| 832 | + public ManagedPipelineMode Xml_PoolPipeLineMode; | |
| 833 | + public string Xml_SitePhysicalPath; | |
| 834 | + public string Xml_IdentityConfigFile; | |
| 835 | + public ProcessModelIdentityType Xml_PoolIdentitytype; | |
| 836 | + public string Xml_PoolUsername; | |
| 837 | + public string Xml_PoolPassword; | |
| 838 | + public bool Xml_RecreatePool; | |
| 839 | + public bool Xml_RecreateSite; | |
| 840 | + public bool Xml_RecreateApp; | |
| 841 | + public bool Xml_ForceRemovePool; | |
| 842 | + public bool Xml_ForceRemoveSite; | |
| 843 | + #endregion properties from Xml definition | |
| 844 | + | |
| 845 | + #region properties from environment | |
| 846 | + public Site Site; | |
| 847 | + public string SitePortList; | |
| 848 | + public string SiteState; | |
| 849 | + public ApplicationPool ApplicationPool; | |
| 850 | + public string PoolState; | |
| 851 | + public string PoolAccount; | |
| 852 | + public string AppImpersonateIdentity; | |
| 853 | + public Application Application; | |
| 854 | + public string ApplicationState; | |
| 855 | + public string ApplicationPath; | |
| 856 | + #endregion properties from environment | |
| 857 | + public WebApplication() { } | |
| 858 | + public WebApplication(XElement webappXml) | |
| 859 | + { | |
| 860 | + string ATTRIBUTEMANDATORY = nameof(XmlStructure.WebApplication) + " attribute is mandatory! Name: {0}"; | |
| 861 | + | |
| 862 | + Xml_AppName = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.Name)))?.Value; | |
| 863 | + if (string.IsNullOrWhiteSpace(Xml_AppName)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WebApplication.Attributes.Name))); } | |
| 864 | + | |
| 865 | + Xml_Description = GetValue(nameof(XmlStructure.WebApplication.Attributes.Description), webappXml, Xml_AppName); | |
| 866 | + Xml_PoolName = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPool), webappXml, XmlStructure.WebApplication.Attributes.AppPool.Values.DEFAULT); | |
| 867 | + Xml_SiteName = GetValue(nameof(XmlStructure.WebApplication.Attributes.WebSite), webappXml, XmlStructure.WebApplication.Attributes.WebSite.Values.DEFAULT); | |
| 868 | + | |
| 869 | + Xml_AppPhysicalPath = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.InstallDir)))?.Value; | |
| 870 | + if (string.IsNullOrWhiteSpace(Xml_AppPhysicalPath)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WebApplication.Attributes.InstallDir))); } | |
| 871 | + | |
| 872 | + string PoolPipeLineModeStr = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.AppPoolPipeLineMode)))?.Value; | |
| 873 | + if (string.IsNullOrWhiteSpace(PoolPipeLineModeStr)) { Xml_PoolPipeLineMode = ManagedPipelineMode.Integrated; } | |
| 874 | + else | |
| 875 | + { | |
| 876 | + Xml_PoolPipeLineMode = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPoolPipeLineMode), webappXml, ManagedPipelineMode.Integrated); | |
| 877 | + } | |
| 878 | + Xml_SitePhysicalPath = GetValue(nameof(XmlStructure.WebApplication.Attributes.SiteRootDir), webappXml, Xml_AppPhysicalPath); | |
| 879 | + Xml_IdentityConfigFile = webappXml.Attribute(XName.Get(nameof(XmlStructure.WebApplication.Attributes.IdentityConfigFile)))?.Value; | |
| 880 | + | |
| 881 | + Xml_PoolUsername = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPoolUsername), webappXml, nameof(ProcessModelIdentityType.ApplicationPoolIdentity)); | |
| 882 | + Xml_PoolPassword = GetValue(nameof(XmlStructure.WebApplication.Attributes.AppPoolPassword), webappXml, ""); | |
| 883 | + try { Xml_PoolIdentitytype = (ProcessModelIdentityType)Enum.Parse(typeof(ProcessModelIdentityType), Xml_PoolUsername); } | |
| 884 | + catch { Xml_PoolIdentitytype = ProcessModelIdentityType.SpecificUser; } | |
| 885 | + if (Xml_PoolIdentitytype != ProcessModelIdentityType.SpecificUser) { Xml_PoolPassword = ""; Xml_PoolUsername = ""; } | |
| 886 | + | |
| 887 | + Xml_RecreatePool = GetValue(nameof(XmlStructure.WebApplication.Attributes.RecreatePool), webappXml, false); | |
| 888 | + Xml_RecreateSite = GetValue(nameof(XmlStructure.WebApplication.Attributes.RecreateSite), webappXml, false); | |
| 889 | + Xml_RecreateApp = GetValue(nameof(XmlStructure.WebApplication.Attributes.RecreateApp), webappXml, true); | |
| 890 | + | |
| 891 | + Xml_ForceRemovePool = GetValue(nameof(XmlStructure.WebApplication.Attributes.ForceRemovePool), webappXml, false); | |
| 892 | + Xml_ForceRemoveSite = GetValue(nameof(XmlStructure.WebApplication.Attributes.ForceRemoveSite), webappXml, false); | |
| 893 | + } | |
| 894 | + public WebApplication(WebApplication wadef) | |
| 895 | + { | |
| 896 | + Xml_AppName = wadef.Xml_AppName; | |
| 897 | + Xml_Description = wadef.Xml_Description; | |
| 898 | + Xml_PoolName = wadef.Xml_PoolName; | |
| 899 | + Xml_SiteName = wadef.Xml_SiteName; | |
| 900 | + Xml_AppPhysicalPath = wadef.Xml_AppPhysicalPath; | |
| 901 | + Xml_SitePhysicalPath = wadef.Xml_SitePhysicalPath; | |
| 902 | + Xml_IdentityConfigFile = wadef.Xml_IdentityConfigFile; | |
| 903 | + Xml_PoolIdentitytype = wadef.Xml_PoolIdentitytype; | |
| 904 | + Xml_RecreateSite = wadef.Xml_RecreateSite; | |
| 905 | + Xml_RecreatePool = wadef.Xml_RecreatePool; | |
| 906 | + Xml_RecreateApp = wadef.Xml_RecreateApp; | |
| 907 | + Xml_ForceRemovePool = wadef.Xml_ForceRemovePool; | |
| 908 | + Xml_ForceRemoveSite = wadef.Xml_ForceRemoveSite; | |
| 909 | + } | |
| 910 | + #region XmlStructure | |
| 911 | + public static class XmlStructure | |
| 912 | + { | |
| 913 | + public static class WebApplication | |
| 914 | + { | |
| 915 | + public static class Attributes | |
| 916 | + { | |
| 917 | + public static class Name { } | |
| 918 | + public static class Description { } | |
| 919 | + public static class AppPool { public static class Values { public const string DEFAULT = "DefaultAppPool"; } } | |
| 920 | + public static class WebSite { public static class Values { public const string DEFAULT = "Default Web Site"; } } | |
| 921 | + public static class InstallDir { } | |
| 922 | + public static class SiteRootDir { } | |
| 923 | + public static class IdentityConfigFile { } | |
| 924 | + public static class AppPoolUsername { } | |
| 925 | + public static class AppPoolPassword { } | |
| 926 | + public static class AppPoolPipeLineMode { } | |
| 927 | + public static class RecreatePool { } | |
| 928 | + public static class RecreateSite { } | |
| 929 | + public static class RecreateApp { } | |
| 930 | + public static class ForceRemovePool { } | |
| 931 | + public static class ForceRemoveSite { } | |
| 932 | + } | |
| 933 | + } | |
| 934 | + } | |
| 935 | + #endregion XmlStructure | |
| 936 | + } | |
| 937 | + #endregion WebApplication class | |
| 938 | + #endregion WebApplicationManager | |
| 939 | +} | ... | ... |
Vrh.Log4Pro.MaintenanceConsole/WindowsServiceManager.cs
0 → 100644
| ... | ... | @@ -0,0 +1,921 @@ |
| 1 | +using System; | |
| 2 | +using System.IO; | |
| 3 | +using System.Configuration.Install; | |
| 4 | +using System.Collections.Generic; | |
| 5 | +using System.Linq; | |
| 6 | +using System.ServiceProcess; | |
| 7 | +using System.Text; | |
| 8 | +using System.Threading; | |
| 9 | +using System.Threading.Tasks; | |
| 10 | + | |
| 11 | +using Microsoft.Web.Administration; | |
| 12 | +using System.Management; | |
| 13 | +using System.Diagnostics; | |
| 14 | + | |
| 15 | +using Vrh.XmlProcessing; | |
| 16 | +using System.Xml.Linq; | |
| 17 | +using System.Text.RegularExpressions; | |
| 18 | + | |
| 19 | +namespace Vrh.Log4Pro.MaintenanceConsole | |
| 20 | +{ | |
| 21 | + #region WindowsServiceManager class | |
| 22 | + public static class WindowsServiceManager | |
| 23 | + { | |
| 24 | + #region Execute | |
| 25 | + public static object Execute(object o1 = null, object o2 = null) | |
| 26 | + { | |
| 27 | + string xmlcs = "file=Config.Xml;element=WindowsServices;"; | |
| 28 | + var config = new WindowsServiceManagerXmlProcessor(xmlcs, "", "hu-HU"); | |
| 29 | + | |
| 30 | + var menufunctions = new Menu("Manage Windows Services", "Select the management function!") | |
| 31 | + .AddMenuItem(new Menu.Item("WSR", "Register", Register)) | |
| 32 | + .AddMenuItem(new Menu.Item("WSU", "Unregister", Unregister)) | |
| 33 | + .AddMenuItem(new Menu.Item("WSS", "Start", Start)) | |
| 34 | + .AddMenuItem(new Menu.Item("WSX", "Stop", Stop)) | |
| 35 | + .AddMenuItem(new Menu.Item("WSK", "Kill", Kill)) | |
| 36 | + .AddMenuItem(new Menu.Item("WSP", "Purge", Purge)) | |
| 37 | + .AddMenuItem(new Menu.Item("WSA", "Set user account", SetUserAccount)) | |
| 38 | + .SetSelectionMode(Menu.SelectionMode.Single); | |
| 39 | + | |
| 40 | + while (true) | |
| 41 | + { | |
| 42 | + Menu.Selection sr; | |
| 43 | + | |
| 44 | + menufunctions.DisplayTitle(); | |
| 45 | + var menuservices = DisplayServices(config); | |
| 46 | + menufunctions.DisplayItems(3, 35); | |
| 47 | + sr = menufunctions.Select(); | |
| 48 | + if (sr.Result == Menu.SelectionResult.Exit) { break; } | |
| 49 | + else if (sr.Result == Menu.SelectionResult.None) { continue; } | |
| 50 | + else if (sr.Result == Menu.SelectionResult.Error) { continue; } | |
| 51 | + menufunctions.SetParameters(sr,config); | |
| 52 | + menufunctions.Execute(sr.SelectedKeyList); | |
| 53 | + } | |
| 54 | + return null; | |
| 55 | + } | |
| 56 | + #endregion Execute | |
| 57 | + | |
| 58 | + public static Menu DisplayServices(WindowsServiceManagerXmlProcessor config,string prompt = null,bool silent=false) | |
| 59 | + { | |
| 60 | + List<WindowsService> wsdefList = config.GetDefinitionList(); | |
| 61 | + var menuservices = new Menu("Windows services",prompt) | |
| 62 | + .SetMenuItemDisplayer(DisplayServiceInfo) | |
| 63 | + .SetSelectionMode(Menu.SelectionMode.Multi) | |
| 64 | + .SetHeaderWidth(4); | |
| 65 | + menuservices.ClearMenuItemList(); | |
| 66 | + foreach (var wsdef in wsdefList) | |
| 67 | + { | |
| 68 | + var w = CollectWindowsServiceInfo(wsdef); | |
| 69 | + menuservices.AddMenuItem(new Menu.Item(null, null, null, w)); | |
| 70 | + } | |
| 71 | + if (!silent) { menuservices.DisplayItems(1); } | |
| 72 | + return menuservices; | |
| 73 | + } | |
| 74 | + | |
| 75 | + #region private method: DisplayServiceInfo | |
| 76 | + private static object DisplayServiceInfo(object wsobj, int lineix) | |
| 77 | + { | |
| 78 | + WindowsService ws = wsobj as WindowsService; | |
| 79 | + if (lineix == 0) | |
| 80 | + { | |
| 81 | + ColorConsole.Write($"{ws.Description}", ConsoleColor.Black, ConsoleColor.White); | |
| 82 | + ColorConsole.WriteLine($"{ws.DisplayName}", bracket: "()"); | |
| 83 | + return ws.DisplayName+ws.Description; | |
| 84 | + } | |
| 85 | + else if (lineix == 1) | |
| 86 | + { | |
| 87 | + ColorConsole.Write($"Win service:"); | |
| 88 | + ColorConsole.Write($"{ws.Name}", ConsoleColor.Cyan); | |
| 89 | + var fc2 = ws.Status.Contains("Unregistered") ? ConsoleColor.Red : ConsoleColor.Green; | |
| 90 | + ColorConsole.Write($"("); | |
| 91 | + ColorConsole.Write($"{ws.Status}", fc2); | |
| 92 | + var fc0 = | |
| 93 | + ws.State.Contains("Started") ? ConsoleColor.Green | |
| 94 | + : ws.State.Contains("Stopped") ? ConsoleColor.Red | |
| 95 | + : ws.State.Contains("Unregistered") ? ConsoleColor.Red | |
| 96 | + : ConsoleColor.Yellow; | |
| 97 | + ColorConsole.Write($" / "); | |
| 98 | + ColorConsole.Write($"{ws.State}", fc0); | |
| 99 | + ColorConsole.Write($")"); | |
| 100 | + ColorConsole.Write($", StartMode:"); | |
| 101 | + ColorConsole.Write($"{ws.StartMode}", ConsoleColor.Cyan); | |
| 102 | + if(ws.Status=="OK" && ws.State != nameof(ObjectState.Stopped) && ws.State != nameof(ObjectState.Unknown)) | |
| 103 | + { | |
| 104 | + ColorConsole.Write($", Priority:"); | |
| 105 | + ColorConsole.Write($"{ws.PriorityClass}", ConsoleColor.White); | |
| 106 | + ColorConsole.Write($", ProcessId:"); | |
| 107 | + ColorConsole.Write($"{ws.ProcessId}", ConsoleColor.White); | |
| 108 | + } | |
| 109 | + ColorConsole.WriteLine(); | |
| 110 | + return ws.Name; | |
| 111 | + } | |
| 112 | + else if (lineix == 2) | |
| 113 | + { | |
| 114 | + if (string.IsNullOrEmpty(ws.PathName)) { return ""; } | |
| 115 | + var cmdarray = CommandLineParser.SplitArgs(ws.PathName).ToArray(); | |
| 116 | + ColorConsole.Write($"Start command:"); | |
| 117 | + ColorConsole.WriteLine($"{cmdarray[0]}", ConsoleColor.White); | |
| 118 | + return ws.PathName; | |
| 119 | + } | |
| 120 | + else if (lineix == 3) | |
| 121 | + { | |
| 122 | + if (string.IsNullOrEmpty(ws.PathName)) { return ""; } | |
| 123 | + var cmdparams = CommandLineParser.SplitArgs(ws.PathName).Skip(1).ToArray(); | |
| 124 | + if (cmdparams.Length==0) { return ""; } | |
| 125 | + var cmdparamsstr = string.Join("][", cmdparams); | |
| 126 | + ColorConsole.Write($"Start arguments:"); | |
| 127 | + ColorConsole.WriteLine($"[{cmdparamsstr}]", ConsoleColor.White); | |
| 128 | + return cmdparamsstr; | |
| 129 | + } | |
| 130 | + else if (lineix == 4) | |
| 131 | + { | |
| 132 | + ColorConsole.Write($"User:"); | |
| 133 | + ColorConsole.WriteLine($"{ws.StartName}", ConsoleColor.White); | |
| 134 | + return ws.StartName; | |
| 135 | + } | |
| 136 | + else if (lineix == 5) | |
| 137 | + { | |
| 138 | + ColorConsole.WriteLine(); | |
| 139 | + return " "; | |
| 140 | + } | |
| 141 | + return null; | |
| 142 | + } | |
| 143 | + #endregion private method: DisplayServiceInfo | |
| 144 | + | |
| 145 | + #region private CollectWindowsServiceInfo | |
| 146 | + private static WindowsService CollectWindowsServiceInfo(WindowsService ws) | |
| 147 | + { | |
| 148 | + using (var wmiService = WindowsServiceManagerCore.GetServiceObject(ws.Name)) | |
| 149 | + { | |
| 150 | + using (var service = WindowsServiceManagerCore.GetServiceController(ws.Name)) | |
| 151 | + { | |
| 152 | + var wmiserviceproblem = false; | |
| 153 | + try { wmiService.Get();}catch { wmiserviceproblem = true; } | |
| 154 | + if (wmiService == null || service == null || wmiserviceproblem) | |
| 155 | + { | |
| 156 | + ws.DisplayName = ws.Xml_DisplayName; | |
| 157 | + ws.Description = ws.Xml_Description; | |
| 158 | + ws.ThisDependsOn = ws.Xml_Dependon; | |
| 159 | + ws.ServicesDependOnThis = new string[] { "???" }; | |
| 160 | + ws.PathName = $"\"{ws.Xml_Exe}\" {ws.Xml_Arguments}"; | |
| 161 | + ws.StartMode = ws.Xml_StartMode; | |
| 162 | + ws.State = "Unregistered"; | |
| 163 | + ws.Status = "Unregistered"; | |
| 164 | + if (ws.Xml_IdentityType== ServiceAccount.User) { ws.StartName = ws.Xml_Username + $"({ws.Xml_Password})"; } | |
| 165 | + else { ws.StartName = ws.Xml_IdentityType.ToString(); } | |
| 166 | + ws.ProcessId = 0; | |
| 167 | + ws.PriorityClass = ws.Xml_Priority; | |
| 168 | + } | |
| 169 | + else | |
| 170 | + { | |
| 171 | + ws.DisplayName = (string)wmiService[nameof(WindowsService.DisplayName)]; | |
| 172 | + ws.Description = (string)wmiService[nameof(WindowsService.Description)]; | |
| 173 | + if (string.IsNullOrEmpty(ws.Description)) { ws.Description = ws.DisplayName; } | |
| 174 | + if (string.IsNullOrEmpty(ws.DisplayName)) { ws.DisplayName = ws.Description; } | |
| 175 | + ws.ServicesDependOnThis = service.DependentServices.Select(s => s.ServiceName).ToArray(); | |
| 176 | + try { ws.ThisDependsOn = service.ServicesDependedOn.Select(s => s.ServiceName).ToArray(); } catch { ws.ThisDependsOn = new string[] { "???" }; } | |
| 177 | + ws.PathName = (string)wmiService[nameof(WindowsService.PathName)];if (ws.PathName == null) { ws.PathName = ""; } | |
| 178 | + var sm = (string)wmiService[nameof(WindowsService.StartMode)]; | |
| 179 | + ws.StartMode = | |
| 180 | + sm == "Auto" ? ServiceStartMode.Automatic | |
| 181 | + : sm == "Auto" ? ServiceStartMode.Manual | |
| 182 | + : sm == "Auto" ? ServiceStartMode.Disabled | |
| 183 | + : sm == "Auto" ? ServiceStartMode.Boot | |
| 184 | + : sm == "Auto" ? ServiceStartMode.System | |
| 185 | + : ServiceStartMode.Manual; | |
| 186 | + ws.State = (string)wmiService[nameof(WindowsService.State)]; | |
| 187 | + ws.Status = (string)wmiService[nameof(WindowsService.Status)]; | |
| 188 | + ws.StartName = (string)wmiService[nameof(WindowsService.StartName)]; | |
| 189 | + ws.ProcessId = 0; | |
| 190 | + ws.PriorityClass = "-"; | |
| 191 | + if (ws.State != nameof(ObjectState.Stopped)) | |
| 192 | + { | |
| 193 | + ws.ProcessId = Convert.ToInt32(wmiService[nameof(WindowsService.ProcessId)]); | |
| 194 | + ws.PriorityClass = Process.GetProcessById(ws.ProcessId).PriorityClass.ToString(); | |
| 195 | + } | |
| 196 | + } | |
| 197 | + } | |
| 198 | + } | |
| 199 | + return ws; | |
| 200 | + } | |
| 201 | + #endregion private CollectWindowsServiceInfo | |
| 202 | + | |
| 203 | + #region First level Executors with UI | |
| 204 | + private static object Purge(object parameter,object o) | |
| 205 | + { | |
| 206 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 207 | + while (true) | |
| 208 | + { | |
| 209 | + ColorConsole.Write($"Enter servicename mask (% and ? are wildchars)!",ConsoleColor.Yellow); | |
| 210 | + var mask = ColorConsole.ReadLine($" ---> ", ConsoleColor.Yellow).ToUpper(); | |
| 211 | + if (mask == "EX") { return o; } | |
| 212 | + else if (mask == "") { continue; } | |
| 213 | + var sl = WindowsServiceManagerCore.GetServiceControllers(mask); | |
| 214 | + if (sl.Length > 10) { sl = sl.Take(10).ToArray(); } | |
| 215 | + | |
| 216 | + var menuservices = new Menu("Windows services", "Select the windows service(es) to delete (max 10 in one run)!") | |
| 217 | + .SetSelectionMode(Menu.SelectionMode.Multi) | |
| 218 | + .SetHeaderWidth(4); | |
| 219 | + | |
| 220 | + for (var i = 0; i < sl.Length; i++) | |
| 221 | + { | |
| 222 | + menuservices.AddMenuItem(new Menu.Item(null, $"{sl[i].ServiceName} ({sl[i].DisplayName})", null, sl[i].ServiceName)); | |
| 223 | + } | |
| 224 | + menuservices.DisplayItems(1); | |
| 225 | + var ms = menuservices.Select(); | |
| 226 | + if (ms.Result == Menu.SelectionResult.None) { continue; } | |
| 227 | + else if (ms.Result == Menu.SelectionResult.Error) { continue; } | |
| 228 | + else if (ms.Result == Menu.SelectionResult.Exit) { break; } | |
| 229 | + else | |
| 230 | + { | |
| 231 | + foreach (var p in ms.SelectedParameterList) | |
| 232 | + { | |
| 233 | + ColorConsole.Write($"Enter CONFIRM to delete service ", ConsoleColor.Yellow); | |
| 234 | + ColorConsole.Write($"{p}", ConsoleColor.White,bracket:"''"); | |
| 235 | + ColorConsole.Write($"!", ConsoleColor.Yellow); | |
| 236 | + var confirmation = ColorConsole.ReadLine(prefix: " ---> ").ToUpper(); | |
| 237 | + if (confirmation == "EX") { return o; } | |
| 238 | + else if (confirmation == "") | |
| 239 | + { | |
| 240 | + ColorConsole.WriteLine($"Service '{p}' skipped!", ConsoleColor.Green); | |
| 241 | + continue; | |
| 242 | + } | |
| 243 | + else if (confirmation == "CONFIRM") | |
| 244 | + { | |
| 245 | + WindowsServiceManagerCore.Unregister((string)p); | |
| 246 | + ColorConsole.WriteLine($"Service '{p}' deleted!", ConsoleColor.Green); | |
| 247 | + } | |
| 248 | + } | |
| 249 | + } | |
| 250 | + } | |
| 251 | + return o; | |
| 252 | + } | |
| 253 | + private static object Kill(object parameter,object o) | |
| 254 | + { | |
| 255 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 256 | + var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Kill)}'!", silent:true); | |
| 257 | + | |
| 258 | + Menu.Selection sr = menuservices.Select(); | |
| 259 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
| 260 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
| 261 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
| 262 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 263 | + else { } | |
| 264 | + foreach (var p in sr.SelectedParameterList) | |
| 265 | + { | |
| 266 | + WindowsService ws = p as WindowsService; | |
| 267 | + try | |
| 268 | + { | |
| 269 | + var success = WindowsServiceManagerCore.Kill(ws.Name); | |
| 270 | + ColorConsole.WriteLine($"Service killed. Name:{ws.Name}", ConsoleColor.Green); | |
| 271 | + } | |
| 272 | + catch (Exception ex) | |
| 273 | + { | |
| 274 | + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); | |
| 275 | + } | |
| 276 | + } | |
| 277 | + return o; | |
| 278 | + } | |
| 279 | + private static object Register(object parameter, object o) | |
| 280 | + { | |
| 281 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 282 | + var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Register)}'!", silent: true); | |
| 283 | + | |
| 284 | + Menu.Selection sr = menuservices.Select(); | |
| 285 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
| 286 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
| 287 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
| 288 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 289 | + else { } | |
| 290 | + foreach (var p in sr.SelectedParameterList) | |
| 291 | + { | |
| 292 | + WindowsService ws = p as WindowsService; | |
| 293 | + try | |
| 294 | + { | |
| 295 | + var success = WindowsServiceManagerCore.Register(ws); | |
| 296 | + ColorConsole.WriteLine($"Service registered. Name:{ws.Name}", ConsoleColor.Green); | |
| 297 | + } | |
| 298 | + catch (Exception ex) | |
| 299 | + { | |
| 300 | + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); | |
| 301 | + } | |
| 302 | + } | |
| 303 | + return o; | |
| 304 | + } | |
| 305 | + private static object Unregister(object parameter,object o) | |
| 306 | + { | |
| 307 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 308 | + var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Unregister)}'!", silent: true); | |
| 309 | + | |
| 310 | + Menu.Selection sr = menuservices.Select(); | |
| 311 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
| 312 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
| 313 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
| 314 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 315 | + else { } | |
| 316 | + foreach (var p in sr.SelectedParameterList) | |
| 317 | + { | |
| 318 | + WindowsService ws = p as WindowsService; | |
| 319 | + try | |
| 320 | + { | |
| 321 | + var success = WindowsServiceManagerCore.Unregister(ws); | |
| 322 | + ColorConsole.WriteLine($"Service unregistered. Name:{ws.Name}", ConsoleColor.Green); | |
| 323 | + } | |
| 324 | + catch (Exception ex) | |
| 325 | + { | |
| 326 | + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); | |
| 327 | + } | |
| 328 | + } | |
| 329 | + return o; | |
| 330 | + } | |
| 331 | + private static object Start(object parameter,object o) | |
| 332 | + { | |
| 333 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 334 | + var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Start)}'!", silent: true); | |
| 335 | + | |
| 336 | + Menu.Selection sr = menuservices.Select(); | |
| 337 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
| 338 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
| 339 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
| 340 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 341 | + else { } | |
| 342 | + foreach (var p in sr.SelectedParameterList) | |
| 343 | + { | |
| 344 | + WindowsService ws = p as WindowsService; | |
| 345 | + try | |
| 346 | + { | |
| 347 | + var success = WindowsServiceManagerCore.Start(ws.Name, ws.Xml_StartTimeout); | |
| 348 | + ColorConsole.WriteLine($"Service started. Name:{ws.Name}", ConsoleColor.Green); | |
| 349 | + } | |
| 350 | + catch (Exception ex) | |
| 351 | + { | |
| 352 | + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); | |
| 353 | + } | |
| 354 | + } | |
| 355 | + return o; | |
| 356 | + } | |
| 357 | + private static object Stop(object parameter,object o) | |
| 358 | + { | |
| 359 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 360 | + var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(Kill)}'!", silent: true); | |
| 361 | + | |
| 362 | + Menu.Selection sr = menuservices.Select(); | |
| 363 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
| 364 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
| 365 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
| 366 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 367 | + else { } | |
| 368 | + foreach (var p in sr.SelectedParameterList) | |
| 369 | + { | |
| 370 | + WindowsService ws = p as WindowsService; | |
| 371 | + try | |
| 372 | + { | |
| 373 | + var success = WindowsServiceManagerCore.Stop(ws.Name, ws.Xml_StopTimeout); | |
| 374 | + ColorConsole.WriteLine($"Service stopped. Name:{ws.Name}", ConsoleColor.Green); | |
| 375 | + } | |
| 376 | + catch (Exception ex) | |
| 377 | + { | |
| 378 | + ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); | |
| 379 | + } | |
| 380 | + } | |
| 381 | + return o; | |
| 382 | + } | |
| 383 | + private static object SetUserAccount(object parameter,object o) | |
| 384 | + { | |
| 385 | + var config = parameter as WindowsServiceManagerXmlProcessor; | |
| 386 | + var menuservices = DisplayServices(config, $"Select the windows service(es) to manage with function '{nameof(SetUserAccount)}'!", silent: true); | |
| 387 | + | |
| 388 | + Menu.Selection sr = menuservices.Select(); | |
| 389 | + if (sr.Result == Menu.SelectionResult.Exit) { return o; } | |
| 390 | + else if (sr.Result == Menu.SelectionResult.None) { return o; } | |
| 391 | + else if (sr.Result == Menu.SelectionResult.Error) { return o; } | |
| 392 | + else if (sr.Result == Menu.SelectionResult.Ok) { } | |
| 393 | + else { } | |
| 394 | + | |
| 395 | + string username = null, password = null; | |
| 396 | + foreach (var p in sr.SelectedParameterList) | |
| 397 | + { | |
| 398 | + WindowsService ws = p as WindowsService; | |
| 399 | + try | |
| 400 | + { | |
| 401 | + using (var wmiService = WindowsServiceManagerCore.GetServiceObject(ws.Name)) | |
| 402 | + { | |
| 403 | + if (username==null) | |
| 404 | + { | |
| 405 | + string olduserinfo = WindowsServiceManagerCore.GetUserInfo(wmiService); | |
| 406 | + ColorConsole.WriteLine($"Current user info: {olduserinfo}"); | |
| 407 | + ColorConsole.WriteLine("Enter username then password. [Enter]=save.EX=exit"); | |
| 408 | + ColorConsole.WriteLine("Username is in the form of 'domainname\\username'"); | |
| 409 | + ColorConsole.WriteLine("Special usernames are: (Empty=API) "); | |
| 410 | + | |
| 411 | + ColorConsole.WriteLine($"LSE", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.LocalService)}"); | |
| 412 | + ColorConsole.WriteLine($"LSY", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.LocalSystem)}"); | |
| 413 | + ColorConsole.WriteLine($"NSE", ConsoleColor.Yellow, bracket: "()", prefix: " ", suffix: $" {nameof(ServiceAccount.NetworkService)}"); | |
| 414 | + | |
| 415 | + ColorConsole.WriteLine(); | |
| 416 | + ColorConsole.WriteLine($"EX", ConsoleColor.Red, bracket: "()", prefix: " ", suffix: " Exit"); | |
| 417 | + | |
| 418 | + username = ColorConsole.ReadLine("username -->", ConsoleColor.Yellow, bracket: "[]"); | |
| 419 | + if (username == "EX") { return null; } | |
| 420 | + else if (string.IsNullOrEmpty(username)) { username = nameof(ServiceAccount.LocalSystem); } | |
| 421 | + else if (username.ToUpper() == "LSE" || username == nameof(ServiceAccount.LocalService)) { username = nameof(ServiceAccount.LocalService); } | |
| 422 | + else if (username.ToUpper() == "LSY" || username == nameof(ServiceAccount.LocalSystem)) { username = nameof(ServiceAccount.LocalSystem); } | |
| 423 | + else if (username.ToUpper() == "NSE" || username == nameof(ServiceAccount.NetworkService)) { username = nameof(ServiceAccount.NetworkService); } | |
| 424 | + else | |
| 425 | + { | |
| 426 | + password = ColorConsole.ReadLine("password -->", ConsoleColor.Yellow, bracket: "[]"); | |
| 427 | + if (password == "EX") { return null; } | |
| 428 | + } | |
| 429 | + } | |
| 430 | + if (WindowsServiceManagerCore.SetUserAccount(wmiService, username, password)) { ColorConsole.WriteLine($"Service user account changed. Name:{ws.Name}", ConsoleColor.Green); } | |
| 431 | + else { ColorConsole.WriteLine($"Service user account change FAILED! Name:{ws.Name}", ConsoleColor.Red); } | |
| 432 | + } | |
| 433 | + } | |
| 434 | + catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); } | |
| 435 | + } | |
| 436 | + return o; | |
| 437 | + } | |
| 438 | + #endregion First level Executors with UI | |
| 439 | + } | |
| 440 | + #endregion WindowsServiceManager class | |
| 441 | + | |
| 442 | + #region WindowsServiceManagerCore class | |
| 443 | + public static class WindowsServiceManagerCore | |
| 444 | + { | |
| 445 | + public static string GetUserInfo(ManagementObject wmiService) | |
| 446 | + { | |
| 447 | + return (string)wmiService[nameof(WindowsService.StartName)]; | |
| 448 | + } | |
| 449 | + public static ManagementObject GetServiceObject(string servicename) { return new ManagementObject("Win32_Service.Name='" + servicename + "'"); } | |
| 450 | + public static ServiceController GetServiceController(string servicename) { return new ServiceController(servicename); } | |
| 451 | + public static ServiceController[] GetServiceControllers(string servicenamemask) | |
| 452 | + { | |
| 453 | + var servicenameregex = @"^" + Regex.Escape(servicenamemask).Replace("%",".*").Replace(@"\?",".")+ @"$"; | |
| 454 | + | |
| 455 | + var ServiceControllerList = new List<ServiceController>(); | |
| 456 | + var allservicecontrollers = ServiceController.GetServices(); | |
| 457 | + foreach (var sc in allservicecontrollers) | |
| 458 | + { | |
| 459 | + try | |
| 460 | + { | |
| 461 | + if (Regex.Match(sc.ServiceName, servicenameregex).Success) { ServiceControllerList.Add(sc); } | |
| 462 | + } | |
| 463 | + catch { ColorConsole.WriteLine($"Error in mask '{servicenamemask}'!",ConsoleColor.Red); return null; } | |
| 464 | + } | |
| 465 | + return ServiceControllerList.ToArray(); | |
| 466 | + } | |
| 467 | + public static bool SetUserAccount(ManagementObject service, string username, string password) | |
| 468 | + { | |
| 469 | + object[] accountParams = new object[11]; | |
| 470 | + accountParams[6] = username; | |
| 471 | + accountParams[7] = password; | |
| 472 | + uint returnCode = (uint)service.InvokeMethod("Change", accountParams); | |
| 473 | + if (returnCode == 0) { return true; } | |
| 474 | + else { return false; } | |
| 475 | + } | |
| 476 | + | |
| 477 | + public static bool Kill(string sname) | |
| 478 | + { | |
| 479 | + using (var wmiService = WindowsServiceManagerCore.GetServiceObject(sname)) | |
| 480 | + { | |
| 481 | + string sstate = (string)wmiService[nameof(WindowsService.State)]; | |
| 482 | + if (sstate != nameof(ObjectState.Stopped)) | |
| 483 | + { | |
| 484 | + int pid = Convert.ToInt32(wmiService[nameof(WindowsService.ProcessId)]); | |
| 485 | + KillProcessAndChildren(pid); | |
| 486 | + } | |
| 487 | + return true; | |
| 488 | + } | |
| 489 | + } | |
| 490 | + | |
| 491 | + /// <summary> | |
| 492 | + /// Kill a process, and all of its children, grandchildren, etc. | |
| 493 | + /// </summary> | |
| 494 | + /// <param name="pid">Process ID.</param> | |
| 495 | + private static void KillProcessAndChildren(int pid) | |
| 496 | + { | |
| 497 | + // Cannot close 'system idle process'. | |
| 498 | + if (pid == 0) { return;} | |
| 499 | + ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid); | |
| 500 | + ManagementObjectCollection moc = searcher.Get(); | |
| 501 | + foreach (ManagementObject mo in moc) { KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); } | |
| 502 | + try { Process proc = Process.GetProcessById(pid); proc.Kill(); } | |
| 503 | + catch (ArgumentException) { } // Process already exited. | |
| 504 | + } | |
| 505 | + public static bool Register(WindowsService ws) | |
| 506 | + { | |
| 507 | + // sc.exe create "ServiceName" binpath= "c:\windows\system32\NewServ.exe" displayname= "Service display name" obj= "username" password="password" start= auto depend= "sname1/sname2/snmae3" | |
| 508 | + // sc.exe \\myserver create NewService binpath= c:\windows\system32\NewServ.exe | |
| 509 | + // sc.exe create NewService binpath= c:\windows\system32\NewServ.exe type= share start= auto depend= +TDI NetBIOS | |
| 510 | + // | |
| 511 | + // sc.exe [<servername>] create [<servicename>] | |
| 512 | + // [type= {own | share | kernel | filesys | rec | interact type= {own | share}}] | |
| 513 | + // [start= {boot | system | auto | demand | disabled | delayed-auto}] | |
| 514 | + // [error= {normal | severe | critical | ignore}] | |
| 515 | + // [binpath= <binarypathname>] | |
| 516 | + // [group= <loadordergroup>] | |
| 517 | + // [tag= {yes | no}] | |
| 518 | + // [depend= <dependencies>] | |
| 519 | + // [obj= {<accountname> | <objectname>}] | |
| 520 | + // [displayname= <displayname>] | |
| 521 | + // [password= <password>] | |
| 522 | + | |
| 523 | + ProcessStartInfo startInfo = new ProcessStartInfo(); | |
| 524 | + startInfo.CreateNoWindow = false; | |
| 525 | + startInfo.UseShellExecute = true; | |
| 526 | + startInfo.FileName = "sc.exe"; | |
| 527 | + startInfo.WindowStyle = ProcessWindowStyle.Hidden; | |
| 528 | + List<string> argumentlist = new List<string>(); | |
| 529 | + argumentlist.Add($"create"); argumentlist.Add(ws.Name.Quote()); | |
| 530 | + argumentlist.Add("displayname="); argumentlist.Add(ws.DisplayName.Quote()); | |
| 531 | + if (ws.Xml_IdentityType == ServiceAccount.User) | |
| 532 | + { | |
| 533 | + argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_Username.Quote()); | |
| 534 | + argumentlist.Add("password="); argumentlist.Add(ws.Xml_Password.Quote()); | |
| 535 | + } | |
| 536 | + else | |
| 537 | + { | |
| 538 | + argumentlist.Add($"obj="); argumentlist.Add(ws.Xml_IdentityType.ToString().Quote()); | |
| 539 | + } | |
| 540 | + var dependonparametert = String.Join("/", ws.Xml_Dependon); | |
| 541 | + argumentlist.Add($"depend="); argumentlist.Add(dependonparametert.Quote()); | |
| 542 | + | |
| 543 | + var startparameter = | |
| 544 | + ws.Xml_StartMode == ServiceStartMode.Automatic ? "auto" | |
| 545 | + : ws.Xml_StartMode == ServiceStartMode.Manual ? "demand" | |
| 546 | + : ws.Xml_StartMode == ServiceStartMode.Disabled ? "disabled" | |
| 547 | + : ws.Xml_StartMode == ServiceStartMode.Boot ? "boot" | |
| 548 | + : "system"; | |
| 549 | + argumentlist.Add($"start="); argumentlist.Add(startparameter.Quote()); | |
| 550 | + | |
| 551 | + var registerarguments = ""; | |
| 552 | + switch (ws.Xml_RegistrationMode) | |
| 553 | + { | |
| 554 | + case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.standard): | |
| 555 | + { | |
| 556 | + registerarguments = ws.Xml_Arguments; | |
| 557 | + } | |
| 558 | + break; | |
| 559 | + case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.topshelf): | |
| 560 | + { | |
| 561 | + //"C:\Log4ProIS\VRH.iLogger\VRH.Common.iLogger.Topshelf.exe" -displayname "VRH iLogger for Log4ProIS" -servicename "VRH iLogger for Log4ProIS" -APPCONFIG appconfigILOGGER.config | |
| 562 | + registerarguments = "-displayname " + ws.Xml_DisplayName.Quote() + " -servicename " + ws.Name.Quote() + " " + ws.Xml_Arguments; | |
| 563 | + } | |
| 564 | + break; | |
| 565 | + case nameof(WindowsService.XmlStructure.WindowsService.Attributes.RegistrationMode.Values.redis): | |
| 566 | + { | |
| 567 | + //"C:\Log4ProIS\VRH.iLogger\VRH.Common.iLogger.Topshelf.exe" -displayname "VRH iLogger for Log4ProIS" -servicename "VRH iLogger for Log4ProIS" -APPCONFIG appconfigILOGGER.config | |
| 568 | + registerarguments = "--service-run " + ws.Xml_Arguments.Quote() + " --service-name " + ws.Name.Quote(); | |
| 569 | + } | |
| 570 | + break; | |
| 571 | + } | |
| 572 | + var binpathparameter = Path.Combine(ws.Xml_InstallDir, ws.Xml_Exe).Quote() + " " + registerarguments; | |
| 573 | + argumentlist.Add($"binpath="); argumentlist.Add(binpathparameter.Quote()); | |
| 574 | + | |
| 575 | + startInfo.Arguments = String.Join(" ", argumentlist); | |
| 576 | + | |
| 577 | + ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments); | |
| 578 | + try | |
| 579 | + { | |
| 580 | + using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } | |
| 581 | + } | |
| 582 | + catch | |
| 583 | + { | |
| 584 | + // Log error. | |
| 585 | + } | |
| 586 | + return true; | |
| 587 | + } | |
| 588 | + | |
| 589 | + public static bool Unregister(WindowsService ws) | |
| 590 | + { | |
| 591 | + return Unregister(ws.Name, ws.Xml_StopTimeout); | |
| 592 | + } | |
| 593 | + public static bool Unregister(string sname,int stoptimeout=10000) | |
| 594 | + { | |
| 595 | + using (var s = GetServiceController(sname)) { Stop(s.ServiceName, stoptimeout); } | |
| 596 | + | |
| 597 | + ProcessStartInfo startInfo = new ProcessStartInfo(); | |
| 598 | + startInfo.CreateNoWindow = false; | |
| 599 | + startInfo.UseShellExecute = true; | |
| 600 | + startInfo.FileName = "sc.exe"; | |
| 601 | + startInfo.WindowStyle = ProcessWindowStyle.Hidden; | |
| 602 | + | |
| 603 | + List<string> argumentlist = new List<string>(); | |
| 604 | + argumentlist.Add($"delete"); argumentlist.Add(sname.Quote()); | |
| 605 | + startInfo.Arguments = String.Join(" ", argumentlist); | |
| 606 | + | |
| 607 | + ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments); | |
| 608 | + try | |
| 609 | + { | |
| 610 | + // Start the process with the info we specified. | |
| 611 | + // Call WaitForExit and then the using statement will close. | |
| 612 | + using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); } | |
| 613 | + } | |
| 614 | + catch | |
| 615 | + { | |
| 616 | + // Log error. | |
| 617 | + } | |
| 618 | + return true; | |
| 619 | + // sc.exe delete "ServiceName" | |
| 620 | + // sc.exe \\myserver delete NewService | |
| 621 | + // | |
| 622 | + // sc.exe | |
| 623 | + // [<servername>] | |
| 624 | + // delete | |
| 625 | + // [<servicename>] | |
| 626 | + } | |
| 627 | + | |
| 628 | + public static bool Start(string sname, int starttimeout) | |
| 629 | + { | |
| 630 | + using (var service = WindowsServiceManagerCore.GetServiceController(sname)) | |
| 631 | + { | |
| 632 | + if (service.ServicesDependedOn.Any()) | |
| 633 | + { | |
| 634 | + bool result = true; | |
| 635 | + foreach (var sn in service.ServicesDependedOn) { result = Start(sn.ServiceName, starttimeout); } | |
| 636 | + } | |
| 637 | + var sl = new List<ServiceControllerStatus>() { ServiceControllerStatus.Running, ServiceControllerStatus.Stopped, ServiceControllerStatus.Paused, }; | |
| 638 | + WaitForStatus(service, sl, starttimeout); | |
| 639 | + if (service.Status.Equals(ServiceControllerStatus.Stopped)) { service.Start(); } | |
| 640 | + else if (service.Status.Equals(ServiceControllerStatus.Running)) {; } | |
| 641 | + else if (service.Status.Equals(ServiceControllerStatus.Paused)) { service.Continue(); } | |
| 642 | + else { throw new Exception($"Start service {service.ServiceName} failed because of incorrect service status!"); } | |
| 643 | + service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 0, 0, starttimeout)); | |
| 644 | + if (!service.Status.Equals(ServiceControllerStatus.Running)) { throw new Exception($"Start service {service.ServiceName} failed!"); } | |
| 645 | + return true; | |
| 646 | + } | |
| 647 | + } | |
| 648 | + public static bool Stop(string sname, int stoptimeout) | |
| 649 | + { | |
| 650 | + using (var service = WindowsServiceManagerCore.GetServiceController(sname)) | |
| 651 | + { | |
| 652 | + if (service.DependentServices.Any()) | |
| 653 | + { | |
| 654 | + bool result = true; | |
| 655 | + foreach (var s in service.ServicesDependedOn) | |
| 656 | + { | |
| 657 | + string sn; | |
| 658 | + try | |
| 659 | + { | |
| 660 | + sn = s.ServiceName; | |
| 661 | + result = Stop(s.ServiceName, stoptimeout); | |
| 662 | + } | |
| 663 | + catch { } | |
| 664 | + } | |
| 665 | + } | |
| 666 | + var sl = new List<ServiceControllerStatus>() { ServiceControllerStatus.Running, ServiceControllerStatus.Stopped, ServiceControllerStatus.Paused, }; | |
| 667 | + WaitForStatus(service, sl, stoptimeout); | |
| 668 | + if (service.Status.Equals(ServiceControllerStatus.Running)) { service.Stop(); } | |
| 669 | + else if (service.Status.Equals(ServiceControllerStatus.Paused)) { service.Stop(); } | |
| 670 | + else if (service.Status.Equals(ServiceControllerStatus.Stopped)) {; } | |
| 671 | + else | |
| 672 | + { | |
| 673 | + try { Kill(sname); } catch { } | |
| 674 | + if (!service.Status.Equals(ServiceControllerStatus.Stopped)) | |
| 675 | + { | |
| 676 | + throw new Exception($"Stop service {service.ServiceName} failed because of incorrect service status!"); | |
| 677 | + } | |
| 678 | + } | |
| 679 | + service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 0, 0, stoptimeout)); | |
| 680 | + if (!service.Status.Equals(ServiceControllerStatus.Stopped)) { throw new Exception($"Stop service {service.ServiceName} failed!"); } | |
| 681 | + return true; | |
| 682 | + } | |
| 683 | + } | |
| 684 | + private async static void WaitForStatus(ServiceController srvCtl, List<ServiceControllerStatus> sl, int toms) | |
| 685 | + { | |
| 686 | + CancellationTokenSource cts = new CancellationTokenSource(); | |
| 687 | + var ct = cts.Token; | |
| 688 | + List<Task> tasks = new List<Task>(); | |
| 689 | + var ts = new TimeSpan(0, 0, 0, 0, toms); | |
| 690 | + foreach (var s in sl) { if (srvCtl.Status.Equals(s)) { return; } }; | |
| 691 | + foreach (var s in sl) { tasks.Add(Task.Run(new Action(() => { try { srvCtl.WaitForStatus(s, ts); } catch { } }), ct)); }; | |
| 692 | + // When any of the tasks completes, it means the service reached on of the statuses you were tracking | |
| 693 | + var t = await Task.WhenAny(tasks); | |
| 694 | + // To cancel the rest of the tasks that are still waiting | |
| 695 | + cts.Cancel(); | |
| 696 | + } | |
| 697 | + | |
| 698 | + } | |
| 699 | + #endregion WindowsServiceManagerCore class | |
| 700 | + #region WindowsServiceManagerXmlProcessor class | |
| 701 | + public class WindowsServiceManagerXmlProcessor : XmlParser | |
| 702 | + { | |
| 703 | + List<WindowsService> _winservicelist; | |
| 704 | + List<WindowsService> _winservicelistinstartorder; | |
| 705 | + List<WindowsService> _winservicelistinstoporder; | |
| 706 | + #region constructor | |
| 707 | + public WindowsServiceManagerXmlProcessor(string xmlcs, string basefolder, string lcid) : base(xmlcs, basefolder, lcid, null) | |
| 708 | + { | |
| 709 | + _winservicelist = new List<WindowsService>(); | |
| 710 | + var wsxmllist = GetAllXElements(nameof(WindowsService.XmlStructure.WindowsService)); | |
| 711 | + if (wsxmllist != null && wsxmllist.Any()) | |
| 712 | + { | |
| 713 | + foreach (var wsxml in wsxmllist) { var ws = new WindowsService(wsxml); if (ws.Valid) { _winservicelist.Add(ws); } } | |
| 714 | + } | |
| 715 | + _winservicelistinstartorder = ProduceDefinitionListInStartOrder(); | |
| 716 | + _winservicelistinstoporder = ProduceDefinitionListInStartOrder(); _winservicelistinstoporder.Reverse(); | |
| 717 | + } | |
| 718 | + #endregion constructor | |
| 719 | + #region GetDefinitionList | |
| 720 | + public List<WindowsService> GetDefinitionList() { return _winservicelist; } | |
| 721 | + public List<WindowsService> GetDefinitionListInStartOrder() { return _winservicelistinstartorder; } | |
| 722 | + public List<WindowsService> GetDefinitionListInStopOrder() { return _winservicelistinstoporder; } | |
| 723 | + private List<WindowsService> ProduceDefinitionListInStartOrder() | |
| 724 | + { | |
| 725 | + List<WindowsService> listinstartorder = new List<WindowsService>(); | |
| 726 | + bool ready = false;//akkor lesz false, ha már minden | |
| 727 | + while (!ready) | |
| 728 | + { | |
| 729 | + ready = true; | |
| 730 | + foreach (var s in _winservicelist) | |
| 731 | + { | |
| 732 | + var namelistinstartorder = listinstartorder.Select(x => x.Name); | |
| 733 | + if (namelistinstartorder.Contains(s.Name)) { continue; }//ez a szerviz már bekerült a startorder listába | |
| 734 | + ready = false; | |
| 735 | + var dl = s.Xml_Dependon; | |
| 736 | + if (dl.Length == 0) { listinstartorder.Add(s); continue; }//ha nem függ senkitől, betesszük a startorder listába | |
| 737 | + foreach (var dli in dl) | |
| 738 | + { | |
| 739 | + if (string.IsNullOrWhiteSpace(dli)) { continue; } | |
| 740 | + if (!namelistinstartorder.Contains(dli)) { continue; }//van egy olyan függősége, ami nincs benne a startorder listában | |
| 741 | + } | |
| 742 | + listinstartorder.Add(s); break;//minden függősége már benne van a start order listában, így ez is bekerül oda | |
| 743 | + } | |
| 744 | + } | |
| 745 | + return listinstartorder; | |
| 746 | + } | |
| 747 | + #endregion GetDefinitionList | |
| 748 | + } | |
| 749 | + #endregion WindowsServiceManagerXmlProcessor class | |
| 750 | + #region WindowsService class | |
| 751 | + public class WindowsService : XmlLinqBase | |
| 752 | + { | |
| 753 | + #region fields | |
| 754 | + public string Name; | |
| 755 | + public bool Valid = true; | |
| 756 | + public string DisplayName; | |
| 757 | + public string Description; | |
| 758 | + public string PathName; | |
| 759 | + public string[] ThisDependsOn; | |
| 760 | + public string[] ServicesDependOnThis; | |
| 761 | + public int ProcessId; | |
| 762 | + public ServiceStartMode StartMode; | |
| 763 | + public string State; | |
| 764 | + public string Status; | |
| 765 | + public string StartName; | |
| 766 | + public string PriorityClass; | |
| 767 | + | |
| 768 | + public string Xml_DisplayName; | |
| 769 | + public string Xml_Description; | |
| 770 | + public string Xml_Exe; | |
| 771 | + public string Xml_InstallDir; | |
| 772 | + public ServiceStartMode Xml_StartMode; | |
| 773 | + public string Xml_Priority; | |
| 774 | + public string Xml_Arguments; | |
| 775 | + public string[] Xml_Dependon; | |
| 776 | + public string Xml_RegistrationMode; | |
| 777 | + public ServiceAccount Xml_IdentityType; | |
| 778 | + public string Xml_Username; | |
| 779 | + public string Xml_Password; | |
| 780 | + public int Xml_StartTimeout; | |
| 781 | + public int Xml_StopTimeout; | |
| 782 | + #endregion fields | |
| 783 | + | |
| 784 | + #region basic constructor | |
| 785 | + public WindowsService() { } | |
| 786 | + #endregion basic constructor | |
| 787 | + #region xml constructor | |
| 788 | + public WindowsService(XElement winservicexml) | |
| 789 | + { | |
| 790 | + string ATTRIBUTEMANDATORY = nameof(XmlStructure.WindowsService) + " attribute is mandatory! Name: {0}"; | |
| 791 | + Name = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Name)))?.Value; | |
| 792 | + if (!ValidServiceName(Name)) | |
| 793 | + { | |
| 794 | + Valid = false; | |
| 795 | + return; | |
| 796 | + //throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Name))); | |
| 797 | + } | |
| 798 | + Xml_DisplayName = GetValue(nameof(XmlStructure.WindowsService.Attributes.DisplayName), winservicexml, Name); | |
| 799 | + Xml_Description = GetValue(nameof(XmlStructure.WindowsService.Attributes.Description), winservicexml, Xml_DisplayName); | |
| 800 | + Xml_Exe = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.Exe)))?.Value; | |
| 801 | + if (string.IsNullOrWhiteSpace(Xml_Exe)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.Exe))); } | |
| 802 | + Xml_InstallDir = winservicexml.Attribute(XName.Get(nameof(XmlStructure.WindowsService.Attributes.InstallDir)))?.Value; | |
| 803 | + if (string.IsNullOrWhiteSpace(Xml_Exe)) { throw new ApplicationException(string.Format(ATTRIBUTEMANDATORY, nameof(XmlStructure.WindowsService.Attributes.InstallDir))); } | |
| 804 | + | |
| 805 | + var startModestr = GetValue(nameof(XmlStructure.WindowsService.Attributes.StartMode), winservicexml, ""); | |
| 806 | + if (string.IsNullOrWhiteSpace(startModestr)) { startModestr = nameof(ServiceStartMode.Manual); } | |
| 807 | + Xml_StartMode = GetValue(startModestr, ServiceStartMode.Manual); | |
| 808 | + | |
| 809 | + Xml_Priority = GetValue(nameof(XmlStructure.WindowsService.Attributes.Priority), winservicexml, XmlStructure.WindowsService.Attributes.Priority.Values.DEFAULT); | |
| 810 | + Xml_Arguments = GetValue(nameof(XmlStructure.WindowsService.Attributes.Arguments), winservicexml, ""); | |
| 811 | + | |
| 812 | + var XmlDependon = new List<string>(); | |
| 813 | + string[] dependonarray = GetValue(nameof(XmlStructure.WindowsService.Attributes.DependOn), winservicexml, "").Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); | |
| 814 | + foreach (var ds in dependonarray) | |
| 815 | + { | |
| 816 | + if (ValidServiceName(ds)) { XmlDependon.Add(ds); } | |
| 817 | + } | |
| 818 | + Xml_Dependon = XmlDependon.ToArray(); | |
| 819 | + | |
| 820 | + Xml_RegistrationMode = GetValue(nameof(XmlStructure.WindowsService.Attributes.RegistrationMode), winservicexml, XmlStructure.WindowsService.Attributes.RegistrationMode.Values.DEFAULT); | |
| 821 | + Xml_RegistrationMode = Xml_RegistrationMode.Replace('-', '_'); | |
| 822 | + try | |
| 823 | + { | |
| 824 | + Xml_IdentityType = GetValue(nameof(XmlStructure.WindowsService.Attributes.UserName), winservicexml, ServiceAccount.LocalSystem); | |
| 825 | + Xml_Username = null; | |
| 826 | + Xml_Password = null; | |
| 827 | + } | |
| 828 | + catch | |
| 829 | + { | |
| 830 | + Xml_IdentityType = ServiceAccount.User; | |
| 831 | + Xml_Username = GetValue(nameof(XmlStructure.WindowsService.Attributes.UserName), winservicexml, XmlStructure.WindowsService.Attributes.UserName.Values.DEFAULT); | |
| 832 | + Xml_Password = GetValue(nameof(XmlStructure.WindowsService.Attributes.Password), winservicexml, ""); | |
| 833 | + } | |
| 834 | + Xml_StartTimeout = GetValue(nameof(XmlStructure.WindowsService.Attributes.StartTimeout), winservicexml, XmlStructure.WindowsService.Attributes.StartTimeout.Values.DEFAULT); | |
| 835 | + Xml_StopTimeout = GetValue(nameof(XmlStructure.WindowsService.Attributes.StopTimeout), winservicexml, XmlStructure.WindowsService.Attributes.StopTimeout.Values.DEFAULT); | |
| 836 | + } | |
| 837 | + private bool ValidServiceName(string sn) { return !string.IsNullOrWhiteSpace(Name) && sn[0] != '@'; } | |
| 838 | + #endregion xml constructor | |
| 839 | + #region cloner constructor | |
| 840 | + public WindowsService(WindowsService ws) | |
| 841 | + { | |
| 842 | + Name = ws.Name; | |
| 843 | + Valid = ws.Valid; | |
| 844 | + Xml_DisplayName = ws.Xml_DisplayName; | |
| 845 | + Xml_Description = ws.Xml_Description; | |
| 846 | + Xml_Exe = ws.Xml_Exe; | |
| 847 | + Xml_InstallDir = ws.Xml_InstallDir; | |
| 848 | + Xml_StartMode = ws.Xml_StartMode; | |
| 849 | + Xml_Priority = ws.Xml_Priority; | |
| 850 | + Xml_Arguments = ws.Xml_Arguments; | |
| 851 | + Xml_Dependon = ws.Xml_Dependon; | |
| 852 | + Xml_RegistrationMode = ws.Xml_RegistrationMode; | |
| 853 | + Xml_IdentityType = ws.Xml_IdentityType; | |
| 854 | + Xml_Username = ws.Xml_Username; | |
| 855 | + Xml_Password = ws.Xml_Password; | |
| 856 | + Xml_StartTimeout = ws.Xml_StartTimeout; | |
| 857 | + Xml_StopTimeout = ws.Xml_StopTimeout; | |
| 858 | + } | |
| 859 | + #endregion cloner constructor | |
| 860 | + #region XmlStructure | |
| 861 | + public static class XmlStructure | |
| 862 | + { | |
| 863 | + public static class WindowsService | |
| 864 | + { | |
| 865 | + public static class Attributes | |
| 866 | + { | |
| 867 | + public static class Name { } | |
| 868 | + public static class DisplayName { } | |
| 869 | + public static class Description { } | |
| 870 | + public static class Exe { } | |
| 871 | + public static class Priority | |
| 872 | + { | |
| 873 | + public static class Values | |
| 874 | + { | |
| 875 | + public static string DEFAULT = "20"; | |
| 876 | + } | |
| 877 | + } | |
| 878 | + public static class StartMode { } | |
| 879 | + public static class InstallDir { } | |
| 880 | + public static class DependOn { } | |
| 881 | + public static class UserName | |
| 882 | + { | |
| 883 | + public static class Values | |
| 884 | + { | |
| 885 | + public static string DEFAULT = nameof(ProcessModelIdentityType.LocalService); | |
| 886 | + } | |
| 887 | + } | |
| 888 | + public static class Password { } | |
| 889 | + public static class Arguments { } | |
| 890 | + public static class StartTimeout | |
| 891 | + { | |
| 892 | + public static class Values | |
| 893 | + { | |
| 894 | + public static int DEFAULT = 10000; | |
| 895 | + } | |
| 896 | + } | |
| 897 | + public static class StopTimeout | |
| 898 | + { | |
| 899 | + public static class Values | |
| 900 | + { | |
| 901 | + public static int DEFAULT = 10000; | |
| 902 | + } | |
| 903 | + } | |
| 904 | + public static class RegistrationMode | |
| 905 | + { | |
| 906 | + public static class Values | |
| 907 | + { | |
| 908 | + public static string DEFAULT = nameof(standard); | |
| 909 | + public class standard { }; | |
| 910 | + public class redis { }; | |
| 911 | + public class topshelf { }; | |
| 912 | + } | |
| 913 | + } | |
| 914 | + } | |
| 915 | + } | |
| 916 | + } | |
| 917 | + #endregion XmlStructure | |
| 918 | + } | |
| 919 | + #endregion WindowsService class | |
| 920 | + | |
| 921 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,140 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8" ?> | |
| 2 | +<XmlParserConfiguration LCID="en-US" NameSeparator="{}@@##||"> | |
| 3 | + <XmlParser> | |
| 4 | + <XmlVar Name="SINGLESERVERIP">127.0.0.1</XmlVar> | |
| 5 | + <XmlVar Name="WEBALMHOST">@SINGLESERVERIP@</XmlVar> | |
| 6 | + <XmlVar Name="WEBALM">WebALM</XmlVar> | |
| 7 | + | |
| 8 | + <XmlVar Name="WEBCPHOST">@SINGLESERVERIP@</XmlVar> | |
| 9 | + <XmlVar Name="WEBCP">WebPack</XmlVar> | |
| 10 | + | |
| 11 | + <XmlVar Name="WEBANDONHOST">@SINGLESERVERIP@</XmlVar> | |
| 12 | + <XmlVar Name="WEBANDON">WebAndon</XmlVar> | |
| 13 | + | |
| 14 | + <!-- A komment be és ki módszert válaszd légyszi, ne írd át! --> | |
| 15 | + <!--<XmlVar Name="APPROOTPATH">d:\!Dev\VRH\LearALMNew</XmlVar>--> | |
| 16 | + <XmlVar Name="APPROOTPATH">c:\Log4ProIS</XmlVar> | |
| 17 | + <XmlVar Name="CENTRALCONFIGPATH">c:\Log4ProIS\CONFIG</XmlVar> | |
| 18 | + <XmlVar Name="ACROOTPATH">@APPROOTPATH@\VRH.Log4Pro.ACALM</XmlVar> | |
| 19 | + | |
| 20 | + <XmlVar Name="WEBAPPROOT">@APPROOTPATH@\wwwroot_Log4ProIS</XmlVar> | |
| 21 | + <XmlVar Name="APPDATA">@WEBAPPROOT@\App_Data</XmlVar> | |
| 22 | + <XmlVar Name="APPDATAALM">@WEBAPPROOT@\App_Data\ALM</XmlVar> | |
| 23 | + <XmlVar Name="APPDATACP">@WEBAPPROOT@\App_Data\CP</XmlVar> | |
| 24 | + <XmlVar Name="APPDATAANDON">@WEBAPPROOT@\App_Data\ANDON</XmlVar> | |
| 25 | + <XmlVar Name="APPDATAISTRM">@WEBAPPROOT@\App_Data\IS-TRM</XmlVar> | |
| 26 | + | |
| 27 | + <XmlVar Name="WEBAPPROOT_WEBPACK">@APPROOTPATH@\wwwroot_WebPack</XmlVar> | |
| 28 | + <XmlVar Name="APPDATA_WEBPACK">@WEBAPPROOT_WEBPACK@\App_Data</XmlVar> | |
| 29 | + | |
| 30 | + <XmlVar Name="WEBAPPROOT_ANDON">@APPROOTPATH@\wwwroot_WebAndon</XmlVar> | |
| 31 | + <XmlVar Name="APPDATA_ANDON">@WEBAPPROOT_ANDON@\App_Data</XmlVar> | |
| 32 | + | |
| 33 | + <XmlVar Name="WEBAPPROOT_ALM">@APPROOTPATH@\wwwroot_WebALM</XmlVar> | |
| 34 | + <XmlVar Name="APPDATA_ALM">@WEBAPPROOT_ALM@\App_Data</XmlVar> | |
| 35 | + | |
| 36 | + <XmlVar Name="DCWF_ALMROOT">@APPROOTPATH@\VRH.Log4Pro.ASEDC-DCWF_ALM\</XmlVar> | |
| 37 | + <XmlVar Name="DCWF_CPROOT">@APPROOTPATH@\VRH.Log4Pro.ASEDC-DCWF_CP\</XmlVar> | |
| 38 | + <XmlVar Name="ASEMON_ROOT">@APPROOTPATH@\VRH.Log4Pro.ASEDC-ASEMON\</XmlVar> | |
| 39 | + | |
| 40 | + <XmlVar Name="ALMSERVERIP">localhost</XmlVar> | |
| 41 | + <XmlVar Name="ALMBACKUPS">c:\Log4ProISBackups</XmlVar> | |
| 42 | + | |
| 43 | + <XmlVar Name="ALMDOCUMENTS">@ALMBACKUPS@\Documents</XmlVar> | |
| 44 | + | |
| 45 | + | |
| 46 | + <XmlVar Name="XMLPARSERBUTTONDEFXML">@APPDATA@\WebMonitor\XmlParserButtonDefinitions.xml</XmlVar> | |
| 47 | + | |
| 48 | + <XmlVar Name="ENABLEDISTRIBUTEWCFCONFIGFILES">false</XmlVar> | |
| 49 | + <XmlVar Name="COMMONSITENAME">SITE_SLNOTEBOOKDELL</XmlVar> | |
| 50 | + </XmlParser> | |
| 51 | + | |
| 52 | + <XmlParser Description="Common menu parameters"> | |
| 53 | + <XmlVar Name="MENUCREATEROLES">true</XmlVar> | |
| 54 | + <XmlVar Name="MENUROLEPREFIX"></XmlVar> | |
| 55 | + <XmlVar Name="MENUCREATEWORDCODES">true</XmlVar> | |
| 56 | + <XmlVar Name="MENUWORDCODEPREFIX">Menu.Xml</XmlVar> | |
| 57 | + <XmlVar Name="MENUGROUPBEHAVIOR">Accordion</XmlVar> | |
| 58 | + <XmlVar Name="STYLE_DIALOG_W40">max-width:40vmax;</XmlVar> | |
| 59 | + <XmlVar Name="STYLE_DIALOG_W80">max-width:80vmax;</XmlVar> | |
| 60 | + <XmlVar Name="STYLE_DIALOG_W120">max-width:120vmax;</XmlVar> | |
| 61 | + <XmlVar Name="STYLE_DIALOG_MENU">max-width:90vmax;margin 100; padding 10;</XmlVar> | |
| 62 | + <XmlVar Name="STYLE_DIALOG_RETURNINFO">max-width:50vmax;font-size:larger;color:white;</XmlVar> | |
| 63 | + <XmlVar Name="STYLE_DIALOG_ENTRYM">max-width:70vmax;font-size:larger;color:white;</XmlVar> | |
| 64 | + <XmlVar Name="STYLE_DIALOG_ENTRYXL">max-width:100vmax;font-size:larger;color:white;</XmlVar> | |
| 65 | + </XmlParser> | |
| 66 | + | |
| 67 | + <Configurations> | |
| 68 | + <Configuration Name="Vrh.Log4Pro.MaintenanceConsole" File="C:\___VCSOLUTIONS\Vrh.Log4Pro.MaintenanceConsole\Vrh.Log4Pro.MaintenanceConsole\Xml.Parser" /> | |
| 69 | + | |
| 70 | + | |
| 71 | + <Configuration Name="VRH.ConnectionStringStore" File="@CENTRALCONFIGPATH@\ConnectionStringStore.xml" /> | |
| 72 | + | |
| 73 | + | |
| 74 | + <Configuration Name="Menu" File="@APPDATA@\Menu\Menu.xml" Element="MainMenu"/> | |
| 75 | + <Configuration Name="RedisScripter" File="@APPDATA@\RedisManager\RedisManagerScripts.xml" /> | |
| 76 | + <Configuration Name="UserAuthentication" File="@APPDATA@\UserAdministration\UserAdministration.xml" /> | |
| 77 | + <Configuration Name="WebForm" File="@APPDATA@\WebForm\WebForms.xml"/> | |
| 78 | + | |
| 79 | + <!--Ezt jelenleg az IdTranslator Web felület használja, mint alapértelmezett XmlConnectionString használja, mint alapértelmezett--> | |
| 80 | + <Configuration Name="IdTranslator" File="@APPDATA@\IdTranslator\IdTranslator.xml"/> | |
| 81 | + | |
| 82 | + <Configuration Name="IVConnector" File="@ACROOTPATH@\IVConnector2.0.0\IVConnector.Config.xml"/> | |
| 83 | + | |
| 84 | + <Configuration Name="DCWF_ALM" File="{DCWF_ALMROOT}DCWF_ALM-parameters.xml" Element="DCWF_ALMParameters"/> | |
| 85 | + <Configuration Name="DCWP_ALM" File="{DCWF_ALMROOT}DCWF_ALM-WP-parameters.xml" Element="DCWP"/> | |
| 86 | + <Configuration Name="DCWPWCF_ALM" File="{DCWF_ALMROOT}DCWF_ALM-WP-parameters.xml" Element="DCWPWCF"/> | |
| 87 | + <Configuration Name="DCWF_ALMMenuPage" File="@APPDATAALM@\DCWF_ALMMenuPage.xml" Element="MenuPageDCWF_ALM"/> | |
| 88 | + <Configuration Name="DCWF_ALMWebMonitorMenuPage" File="@APPDATAALM@\DCWF_ALMMenuPage.xml" Element="MenuPageWebMonitor"/> | |
| 89 | + <!--<Configuration Name="DCWF_ALMOneReportMenuPage" File="@APPDATAALM@\DCWF_ALMMenuPage.xml" Element="MenuPageOneReport"/>--> | |
| 90 | + | |
| 91 | + <Configuration Name="DCWF_ALMOneReportWebForms" File="@APPDATAALM@\OneReport\OneReports.xml" Element="WebFormXML"/> | |
| 92 | + <Configuration Name="DCWF_ALMOneReportMenuPage" File="@APPDATAALM@\OneReport\OneReports.xml" Element="MenuPageOneReport"/> | |
| 93 | + <Configuration Name="ALM_OneReport" File="@APPDATAALM@\OneReport\OneReports.xml" Element="ReportDefinitions"/> | |
| 94 | + | |
| 95 | + <Configuration Name="DCWF_ALMFileManagerMenuPage" File="@APPDATAALM@\DCWF_ALMMenuPage.xml" Element="MenuPageFileManager"/> | |
| 96 | + <Configuration Name="DCWF_ALMOneScripter" File="@APPDATAALM@\OneScripter\OneScripterMenuPage.xml" /> | |
| 97 | + <Configuration Name="DCWF_ALMRedisManager" File="@APPDATAALM@\RedisManager\RedisManagerConfig.xml" /> | |
| 98 | + <Configuration Name="DCWF_ALMServiceControl" File="@APPDATAALM@\ServiceControl\ServiceControlConfig.xml" /> | |
| 99 | + <Configuration Name="DCWF_ALMASEMWManager" File="@APPDATAALM@\AseMwManager\AseMwManager.xml" /> | |
| 100 | + <Configuration Name="DCWF_ALMConfigEditorMenuPage" File="@APPDATAALM@\ConfigEditor\ConfigEditorALMMenuPage.xml" /> | |
| 101 | + <Configuration Name="InterventionDCWFWCF_ALMInterventionService" File="@APPDATAALM@\Interventions\DCWF_ALMInterventions.xml"/> | |
| 102 | + <Configuration Name="InterventionDTMInterventionService" File="@APPDATAALM@\Interventions\ALMInterventions.xml"/> | |
| 103 | + <Configuration Name="DCWF_ALMConfigEditor" File="@APPDATAALM@\ConfigEditor\ConfigEditorALM.xml" /> | |
| 104 | + <Configuration Name="DCWF_ALMiSchedulerReportMenuPage" File="@APPDATAALM@\DCWF_ALMMenuPage.xml" Element="MenuPageiSchedulerReport" /> | |
| 105 | + <Configuration Name="DCWF_ALMiScheduler" File="@APPDATAALM@\iScheduler\iScheduler.xml"/> | |
| 106 | + <Configuration Name="DCWF_ALMiSchedulerReport" File="@APPDATAALM@\iScheduler\iSchedulerReport.xml"/> | |
| 107 | + <Configuration Name="DCWF_ALMiSchedulerWebForms" File="@APPDATAALM@\iScheduler\iSchedulerWebforms.xml"/> | |
| 108 | + <Configuration Name="SelectListsALM" File="@APPDATAALM@\Intervention\DCWF_ALMSelectLists.xml"/> | |
| 109 | + <Configuration Name="ALM_WebMonitor" File="@APPDATAALM@\WebMonitor\WebMonitor.xml"/> | |
| 110 | + <Configuration Name="ALM_Matrix1D" File="@APPDATAALM@\WebMonitor\Matrix1D.xml"/> | |
| 111 | + <Configuration Name="ALM_Matrix2D" File="@APPDATAALM@\WebMonitor\Matrix2D.xml"/> | |
| 112 | + <Configuration Name="ALM_TrendDiagram" File="@APPDATAALM@\WebMonitor\TrendDiagram.xml"/> | |
| 113 | + | |
| 114 | + <Configuration Name="ISTRM_MenuPage" File="@APPDATAISTRM@\ISTRMMenuPage.xml" Element="MenuPageISTRM"/> | |
| 115 | + <Configuration Name="ISTRM_WebMonitor" File="@APPDATAISTRM@\WebMonitor\WebMonitor.xml"/> | |
| 116 | + <Configuration Name="ISTRM_Matrix2D" File="@APPDATAISTRM@\WebMonitor\Matrix2D.xml"/> | |
| 117 | + | |
| 118 | + | |
| 119 | + <Configuration Name="ANDONMenuPage" File="@APPDATAANDON@\ANDONMenuPage.xml" Element="MenuPageAndon"/> | |
| 120 | + <Configuration Name="ANDONConfig" File="@APPDATAANDON@\Andon.Config.XML"/> | |
| 121 | + <Configuration Name="ANDONRedisManager" File="@APPDATAANDON@\Andon.Config.XML" Element="RedisManager" /> | |
| 122 | + | |
| 123 | + <Configuration Name="DCWF_CP" File="{DCWF_CPROOT}DCWF_CP-parameters.xml"/> | |
| 124 | + <Configuration Name="DCWP_CP" File="{DCWF_CPROOT}DCWF_CP-WP-parameters.xml" Element="DCWP"/> | |
| 125 | + <Configuration Name="DCWPWCF_CP" File="{DCWF_CPROOT}DCWF_CP-WP-parameters.xml" Element="DCWPWCF"/> | |
| 126 | + <Configuration Name="DCWF_CP_ivConnectorOut" File="{DCWF_CPROOT}DCWF_CP-IVCONNECTOR.xml"/> | |
| 127 | + <Configuration Name="DCWF_CPMenuPage" File="@APPDATACP@\DCWF_CPMenuPage.xml" Element="MenuPageDCWF_CP"/> | |
| 128 | + <Configuration Name="DCWF_CPASEMWManager" File="@APPDATACP@\AseMwManager\AseMwManager.xml" /> | |
| 129 | + <Configuration Name="DCWF_CPServiceControl" File="@APPDATACP@\ServiceControl\ServiceControlConfig.xml" /> | |
| 130 | + <Configuration Name="DCWF_CPRedisManager" File="@APPDATACP@\RedisManager\RedisManagerConfig.xml" /> | |
| 131 | + <Configuration Name="CPConfig" File="@APPDATACP@\CPConfiguration.xml" /> | |
| 132 | + <Configuration Name="InterventionDCWFWCF_CPInterventionService" File="@APPDATACP@\Interventions\DCWF_CPInterventions.xml"/> | |
| 133 | + <Configuration Name="SelectListsCP" File="@APPDATACP@\Interventions\DCWF_CPSelectLists.xml"/> | |
| 134 | + <Configuration Name="ConfigEditorCP" File="@APPDATACP@\ConfigEditor\ConfigEditorCP.xml" /> | |
| 135 | + <Configuration Name="WebMonitorCP" File="@APPDATACP@\WebMonitor\WebMonitorCP.xml"/> | |
| 136 | + <Configuration Name="Matrix1DCP" File="@APPDATACP@\WebMonitor\Matrix1DCP.xml"/> | |
| 137 | + <Configuration Name="Matrix2DCP" File="@APPDATACP@\WebMonitor\Matrix2DCP.xml"/> | |
| 138 | + | |
| 139 | + </Configurations> | |
| 140 | +</XmlParserConfiguration> | |
| 0 | 141 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<packages> | |
| 3 | + <package id="Microsoft.NETCore.Platforms" version="1.0.1" targetFramework="net462" /> | |
| 4 | + <package id="Microsoft.Web.Administration" version="11.1.0" targetFramework="net462" /> | |
| 5 | + <package id="Microsoft.Win32.Primitives" version="4.0.1" targetFramework="net462" /> | |
| 6 | + <package id="Microsoft.Win32.Registry" version="4.0.0" targetFramework="net462" /> | |
| 7 | + <package id="NETStandard.Library" version="1.6.0" targetFramework="net462" /> | |
| 8 | + <package id="System.AppContext" version="4.1.0" targetFramework="net462" /> | |
| 9 | + <package id="System.Collections" version="4.0.11" targetFramework="net462" /> | |
| 10 | + <package id="System.Collections.Concurrent" version="4.0.12" targetFramework="net462" /> | |
| 11 | + <package id="System.Console" version="4.0.0" targetFramework="net462" /> | |
| 12 | + <package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="net462" /> | |
| 13 | + <package id="System.Diagnostics.DiagnosticSource" version="4.0.0" targetFramework="net462" /> | |
| 14 | + <package id="System.Diagnostics.Tools" version="4.0.1" targetFramework="net462" /> | |
| 15 | + <package id="System.Diagnostics.TraceSource" version="4.0.0" targetFramework="net462" /> | |
| 16 | + <package id="System.Diagnostics.Tracing" version="4.1.0" targetFramework="net462" /> | |
| 17 | + <package id="System.Globalization" version="4.0.11" targetFramework="net462" /> | |
| 18 | + <package id="System.Globalization.Calendars" version="4.0.1" targetFramework="net462" /> | |
| 19 | + <package id="System.IO" version="4.1.0" targetFramework="net462" /> | |
| 20 | + <package id="System.IO.Compression" version="4.1.0" targetFramework="net462" /> | |
| 21 | + <package id="System.IO.Compression.ZipFile" version="4.0.1" targetFramework="net462" /> | |
| 22 | + <package id="System.IO.FileSystem" version="4.0.1" targetFramework="net462" /> | |
| 23 | + <package id="System.IO.FileSystem.Primitives" version="4.0.1" targetFramework="net462" /> | |
| 24 | + <package id="System.Linq" version="4.1.0" targetFramework="net462" /> | |
| 25 | + <package id="System.Linq.Expressions" version="4.1.0" targetFramework="net462" /> | |
| 26 | + <package id="System.Management" version="5.0.0" targetFramework="net462" /> | |
| 27 | + <package id="System.Net.Http" version="4.1.0" targetFramework="net462" /> | |
| 28 | + <package id="System.Net.Primitives" version="4.0.11" targetFramework="net462" /> | |
| 29 | + <package id="System.Net.Sockets" version="4.1.0" targetFramework="net462" /> | |
| 30 | + <package id="System.ObjectModel" version="4.0.12" targetFramework="net462" /> | |
| 31 | + <package id="System.Reflection" version="4.1.0" targetFramework="net462" /> | |
| 32 | + <package id="System.Reflection.Extensions" version="4.0.1" targetFramework="net462" /> | |
| 33 | + <package id="System.Reflection.Primitives" version="4.0.1" targetFramework="net462" /> | |
| 34 | + <package id="System.Reflection.TypeExtensions" version="4.4.0" targetFramework="net462" /> | |
| 35 | + <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="net462" /> | |
| 36 | + <package id="System.Runtime" version="4.1.0" targetFramework="net462" /> | |
| 37 | + <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net462" /> | |
| 38 | + <package id="System.Runtime.Handles" version="4.0.1" targetFramework="net462" /> | |
| 39 | + <package id="System.Runtime.InteropServices" version="4.1.0" targetFramework="net462" /> | |
| 40 | + <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.0.0" targetFramework="net462" /> | |
| 41 | + <package id="System.Runtime.Numerics" version="4.0.1" targetFramework="net462" /> | |
| 42 | + <package id="System.Security.Claims" version="4.0.1" targetFramework="net462" /> | |
| 43 | + <package id="System.Security.Cryptography.Algorithms" version="4.2.0" targetFramework="net462" /> | |
| 44 | + <package id="System.Security.Cryptography.Encoding" version="4.0.0" targetFramework="net462" /> | |
| 45 | + <package id="System.Security.Cryptography.Primitives" version="4.0.0" targetFramework="net462" /> | |
| 46 | + <package id="System.Security.Cryptography.X509Certificates" version="4.1.0" targetFramework="net462" /> | |
| 47 | + <package id="System.Security.Principal.Windows" version="4.0.0" targetFramework="net462" /> | |
| 48 | + <package id="System.ServiceProcess.ServiceController" version="4.1.0" targetFramework="net462" /> | |
| 49 | + <package id="System.Text.Encoding" version="4.0.11" targetFramework="net462" /> | |
| 50 | + <package id="System.Text.Encoding.Extensions" version="4.0.11" targetFramework="net462" /> | |
| 51 | + <package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="net462" /> | |
| 52 | + <package id="System.Threading" version="4.0.11" targetFramework="net462" /> | |
| 53 | + <package id="System.Threading.Tasks" version="4.0.11" targetFramework="net462" /> | |
| 54 | + <package id="System.Threading.Timer" version="4.0.1" targetFramework="net462" /> | |
| 55 | + <package id="System.Xml.ReaderWriter" version="4.0.11" targetFramework="net462" /> | |
| 56 | + <package id="System.Xml.XDocument" version="4.0.11" targetFramework="net462" /> | |
| 57 | + <package id="Vrh.XmlProcessing" version="1.23.0" targetFramework="net462" /> | |
| 58 | +</packages> | |
| 0 | 59 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.Linq; | |
| 4 | +using System.ServiceProcess; | |
| 5 | +using System.Text; | |
| 6 | +using System.Threading.Tasks; | |
| 7 | + | |
| 8 | +namespace WindowsService1 | |
| 9 | +{ | |
| 10 | + static class Program | |
| 11 | + { | |
| 12 | + /// <summary> | |
| 13 | + /// The main entry point for the application. | |
| 14 | + /// </summary> | |
| 15 | + static void Main() | |
| 16 | + { | |
| 17 | + ServiceBase[] ServicesToRun; | |
| 18 | + ServicesToRun = new ServiceBase[] | |
| 19 | + { | |
| 20 | + new Service1() | |
| 21 | + }; | |
| 22 | + ServiceBase.Run(ServicesToRun); | |
| 23 | + } | |
| 24 | + } | |
| 25 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | + | |
| 2 | +namespace WindowsService1 | |
| 3 | +{ | |
| 4 | + partial class ProjectInstaller | |
| 5 | + { | |
| 6 | + /// <summary> | |
| 7 | + /// Required designer variable. | |
| 8 | + /// </summary> | |
| 9 | + private System.ComponentModel.IContainer components = null; | |
| 10 | + | |
| 11 | + /// <summary> | |
| 12 | + /// Clean up any resources being used. | |
| 13 | + /// </summary> | |
| 14 | + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |
| 15 | + protected override void Dispose(bool disposing) | |
| 16 | + { | |
| 17 | + if (disposing && (components != null)) | |
| 18 | + { | |
| 19 | + components.Dispose(); | |
| 20 | + } | |
| 21 | + base.Dispose(disposing); | |
| 22 | + } | |
| 23 | + | |
| 24 | + #region Component Designer generated code | |
| 25 | + | |
| 26 | + /// <summary> | |
| 27 | + /// Required method for Designer support - do not modify | |
| 28 | + /// the contents of this method with the code editor. | |
| 29 | + /// </summary> | |
| 30 | + private void InitializeComponent() | |
| 31 | + { | |
| 32 | + this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller(); | |
| 33 | + this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller(); | |
| 34 | + // | |
| 35 | + // serviceProcessInstaller1 | |
| 36 | + // | |
| 37 | + this.serviceProcessInstaller1.Password = null; | |
| 38 | + this.serviceProcessInstaller1.Username = null; | |
| 39 | + //this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.; | |
| 40 | + // | |
| 41 | + // serviceInstaller1 | |
| 42 | + // | |
| 43 | + this.serviceInstaller1.ServiceName = "Service1"; | |
| 44 | + //this.serviceInstaller1. = "Service1"; | |
| 45 | + // | |
| 46 | + // ProjectInstaller | |
| 47 | + // | |
| 48 | + this.Installers.AddRange(new System.Configuration.Install.Installer[] { | |
| 49 | + this.serviceProcessInstaller1, | |
| 50 | + this.serviceInstaller1}); | |
| 51 | + | |
| 52 | + } | |
| 53 | + | |
| 54 | + #endregion | |
| 55 | + | |
| 56 | + private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; | |
| 57 | + private System.ServiceProcess.ServiceInstaller serviceInstaller1; | |
| 58 | + } | |
| 59 | +} | |
| 0 | 60 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | +using System; | |
| 2 | +using System.Collections; | |
| 3 | +using System.Collections.Generic; | |
| 4 | +using System.ComponentModel; | |
| 5 | +using System.Configuration.Install; | |
| 6 | +using System.Linq; | |
| 7 | +using System.Threading.Tasks; | |
| 8 | + | |
| 9 | +namespace WindowsService1 | |
| 10 | +{ | |
| 11 | + [RunInstaller(true)] | |
| 12 | + public partial class ProjectInstaller : System.Configuration.Install.Installer | |
| 13 | + { | |
| 14 | + public ProjectInstaller() | |
| 15 | + { | |
| 16 | + InitializeComponent(); | |
| 17 | + } | |
| 18 | + } | |
| 19 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,129 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<root> | |
| 3 | + <!-- | |
| 4 | + Microsoft ResX Schema | |
| 5 | + | |
| 6 | + Version 2.0 | |
| 7 | + | |
| 8 | + The primary goals of this format is to allow a simple XML format | |
| 9 | + that is mostly human readable. The generation and parsing of the | |
| 10 | + various data types are done through the TypeConverter classes | |
| 11 | + associated with the data types. | |
| 12 | + | |
| 13 | + Example: | |
| 14 | + | |
| 15 | + ... ado.net/XML headers & schema ... | |
| 16 | + <resheader name="resmimetype">text/microsoft-resx</resheader> | |
| 17 | + <resheader name="version">2.0</resheader> | |
| 18 | + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |
| 19 | + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |
| 20 | + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |
| 21 | + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |
| 22 | + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |
| 23 | + <value>[base64 mime encoded serialized .NET Framework object]</value> | |
| 24 | + </data> | |
| 25 | + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |
| 26 | + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |
| 27 | + <comment>This is a comment</comment> | |
| 28 | + </data> | |
| 29 | + | |
| 30 | + There are any number of "resheader" rows that contain simple | |
| 31 | + name/value pairs. | |
| 32 | + | |
| 33 | + Each data row contains a name, and value. The row also contains a | |
| 34 | + type or mimetype. Type corresponds to a .NET class that support | |
| 35 | + text/value conversion through the TypeConverter architecture. | |
| 36 | + Classes that don't support this are serialized and stored with the | |
| 37 | + mimetype set. | |
| 38 | + | |
| 39 | + The mimetype is used for serialized objects, and tells the | |
| 40 | + ResXResourceReader how to depersist the object. This is currently not | |
| 41 | + extensible. For a given mimetype the value must be set accordingly: | |
| 42 | + | |
| 43 | + Note - application/x-microsoft.net.object.binary.base64 is the format | |
| 44 | + that the ResXResourceWriter will generate, however the reader can | |
| 45 | + read any of the formats listed below. | |
| 46 | + | |
| 47 | + mimetype: application/x-microsoft.net.object.binary.base64 | |
| 48 | + value : The object must be serialized with | |
| 49 | + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |
| 50 | + : and then encoded with base64 encoding. | |
| 51 | + | |
| 52 | + mimetype: application/x-microsoft.net.object.soap.base64 | |
| 53 | + value : The object must be serialized with | |
| 54 | + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |
| 55 | + : and then encoded with base64 encoding. | |
| 56 | + | |
| 57 | + mimetype: application/x-microsoft.net.object.bytearray.base64 | |
| 58 | + value : The object must be serialized into a byte array | |
| 59 | + : using a System.ComponentModel.TypeConverter | |
| 60 | + : and then encoded with base64 encoding. | |
| 61 | + --> | |
| 62 | + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |
| 63 | + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |
| 64 | + <xsd:element name="root" msdata:IsDataSet="true"> | |
| 65 | + <xsd:complexType> | |
| 66 | + <xsd:choice maxOccurs="unbounded"> | |
| 67 | + <xsd:element name="metadata"> | |
| 68 | + <xsd:complexType> | |
| 69 | + <xsd:sequence> | |
| 70 | + <xsd:element name="value" type="xsd:string" minOccurs="0" /> | |
| 71 | + </xsd:sequence> | |
| 72 | + <xsd:attribute name="name" use="required" type="xsd:string" /> | |
| 73 | + <xsd:attribute name="type" type="xsd:string" /> | |
| 74 | + <xsd:attribute name="mimetype" type="xsd:string" /> | |
| 75 | + <xsd:attribute ref="xml:space" /> | |
| 76 | + </xsd:complexType> | |
| 77 | + </xsd:element> | |
| 78 | + <xsd:element name="assembly"> | |
| 79 | + <xsd:complexType> | |
| 80 | + <xsd:attribute name="alias" type="xsd:string" /> | |
| 81 | + <xsd:attribute name="name" type="xsd:string" /> | |
| 82 | + </xsd:complexType> | |
| 83 | + </xsd:element> | |
| 84 | + <xsd:element name="data"> | |
| 85 | + <xsd:complexType> | |
| 86 | + <xsd:sequence> | |
| 87 | + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |
| 88 | + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |
| 89 | + </xsd:sequence> | |
| 90 | + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |
| 91 | + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |
| 92 | + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |
| 93 | + <xsd:attribute ref="xml:space" /> | |
| 94 | + </xsd:complexType> | |
| 95 | + </xsd:element> | |
| 96 | + <xsd:element name="resheader"> | |
| 97 | + <xsd:complexType> | |
| 98 | + <xsd:sequence> | |
| 99 | + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |
| 100 | + </xsd:sequence> | |
| 101 | + <xsd:attribute name="name" type="xsd:string" use="required" /> | |
| 102 | + </xsd:complexType> | |
| 103 | + </xsd:element> | |
| 104 | + </xsd:choice> | |
| 105 | + </xsd:complexType> | |
| 106 | + </xsd:element> | |
| 107 | + </xsd:schema> | |
| 108 | + <resheader name="resmimetype"> | |
| 109 | + <value>text/microsoft-resx</value> | |
| 110 | + </resheader> | |
| 111 | + <resheader name="version"> | |
| 112 | + <value>2.0</value> | |
| 113 | + </resheader> | |
| 114 | + <resheader name="reader"> | |
| 115 | + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |
| 116 | + </resheader> | |
| 117 | + <resheader name="writer"> | |
| 118 | + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |
| 119 | + </resheader> | |
| 120 | + <metadata name="serviceProcessInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |
| 121 | + <value>17, 17</value> | |
| 122 | + </metadata> | |
| 123 | + <metadata name="serviceInstaller1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |
| 124 | + <value>196, 17</value> | |
| 125 | + </metadata> | |
| 126 | + <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> | |
| 127 | + <value>False</value> | |
| 128 | + </metadata> | |
| 129 | +</root> | |
| 0 | 130 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | +using System.Reflection; | |
| 2 | +using System.Runtime.CompilerServices; | |
| 3 | +using System.Runtime.InteropServices; | |
| 4 | + | |
| 5 | +// General Information about an assembly is controlled through the following | |
| 6 | +// set of attributes. Change these attribute values to modify the information | |
| 7 | +// associated with an assembly. | |
| 8 | +[assembly: AssemblyTitle("WindowsService1")] | |
| 9 | +[assembly: AssemblyDescription("")] | |
| 10 | +[assembly: AssemblyConfiguration("")] | |
| 11 | +[assembly: AssemblyCompany("Microsoft")] | |
| 12 | +[assembly: AssemblyProduct("WindowsService1")] | |
| 13 | +[assembly: AssemblyCopyright("Copyright © Microsoft 2020")] | |
| 14 | +[assembly: AssemblyTrademark("")] | |
| 15 | +[assembly: AssemblyCulture("")] | |
| 16 | + | |
| 17 | +// Setting ComVisible to false makes the types in this assembly not visible | |
| 18 | +// to COM components. If you need to access a type in this assembly from | |
| 19 | +// COM, set the ComVisible attribute to true on that type. | |
| 20 | +[assembly: ComVisible(false)] | |
| 21 | + | |
| 22 | +// The following GUID is for the ID of the typelib if this project is exposed to COM | |
| 23 | +[assembly: Guid("c02910b6-11c6-4e58-b830-3f64caed0eb5")] | |
| 24 | + | |
| 25 | +// Version information for an assembly consists of the following four values: | |
| 26 | +// | |
| 27 | +// Major Version | |
| 28 | +// Minor Version | |
| 29 | +// Build Number | |
| 30 | +// Revision | |
| 31 | +// | |
| 32 | +// You can specify all the values or you can default the Build and Revision Numbers | |
| 33 | +// by using the '*' as shown below: | |
| 34 | +// [assembly: AssemblyVersion("1.0.*")] | |
| 35 | +[assembly: AssemblyVersion("1.0.0.0")] | |
| 36 | +[assembly: AssemblyFileVersion("1.0.0.0")] | ... | ... |
| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | + | |
| 2 | +namespace WindowsService1 | |
| 3 | +{ | |
| 4 | + partial class Service1 | |
| 5 | + { | |
| 6 | + /// <summary> | |
| 7 | + /// Required designer variable. | |
| 8 | + /// </summary> | |
| 9 | + private System.ComponentModel.IContainer components = null; | |
| 10 | + | |
| 11 | + /// <summary> | |
| 12 | + /// Clean up any resources being used. | |
| 13 | + /// </summary> | |
| 14 | + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |
| 15 | + protected override void Dispose(bool disposing) | |
| 16 | + { | |
| 17 | + if (disposing && (components != null)) | |
| 18 | + { | |
| 19 | + components.Dispose(); | |
| 20 | + } | |
| 21 | + base.Dispose(disposing); | |
| 22 | + } | |
| 23 | + | |
| 24 | + #region Component Designer generated code | |
| 25 | + | |
| 26 | + /// <summary> | |
| 27 | + /// Required method for Designer support - do not modify | |
| 28 | + /// the contents of this method with the code editor. | |
| 29 | + /// </summary> | |
| 30 | + private void InitializeComponent() | |
| 31 | + { | |
| 32 | + components = new System.ComponentModel.Container(); | |
| 33 | + this.ServiceName = "Service1"; | |
| 34 | + } | |
| 35 | + | |
| 36 | + #endregion | |
| 37 | + } | |
| 38 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | +using System; | |
| 2 | +using System.Collections.Generic; | |
| 3 | +using System.ComponentModel; | |
| 4 | +using System.Data; | |
| 5 | +using System.Diagnostics; | |
| 6 | +using System.Linq; | |
| 7 | +using System.ServiceProcess; | |
| 8 | +using System.Text; | |
| 9 | +using System.Threading.Tasks; | |
| 10 | + | |
| 11 | +namespace WindowsService1 | |
| 12 | +{ | |
| 13 | + public partial class Service1 : ServiceBase | |
| 14 | + { | |
| 15 | + public Service1() | |
| 16 | + { | |
| 17 | + InitializeComponent(); | |
| 18 | + } | |
| 19 | + | |
| 20 | + protected override void OnStart(string[] args) | |
| 21 | + { | |
| 22 | + } | |
| 23 | + | |
| 24 | + protected override void OnStop() | |
| 25 | + { | |
| 26 | + } | |
| 27 | + } | |
| 28 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,73 @@ |
| 1 | +<?xml version="1.0" encoding="utf-8"?> | |
| 2 | +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
| 3 | + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |
| 4 | + <PropertyGroup> | |
| 5 | + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |
| 6 | + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |
| 7 | + <ProjectGuid>{C02910B6-11C6-4E58-B830-3F64CAED0EB5}</ProjectGuid> | |
| 8 | + <OutputType>WinExe</OutputType> | |
| 9 | + <RootNamespace>WindowsService1</RootNamespace> | |
| 10 | + <AssemblyName>WindowsService1</AssemblyName> | |
| 11 | + <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion> | |
| 12 | + <FileAlignment>512</FileAlignment> | |
| 13 | + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> | |
| 14 | + <Deterministic>true</Deterministic> | |
| 15 | + </PropertyGroup> | |
| 16 | + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |
| 17 | + <PlatformTarget>AnyCPU</PlatformTarget> | |
| 18 | + <DebugSymbols>true</DebugSymbols> | |
| 19 | + <DebugType>full</DebugType> | |
| 20 | + <Optimize>false</Optimize> | |
| 21 | + <OutputPath>bin\Debug\</OutputPath> | |
| 22 | + <DefineConstants>DEBUG;TRACE</DefineConstants> | |
| 23 | + <ErrorReport>prompt</ErrorReport> | |
| 24 | + <WarningLevel>4</WarningLevel> | |
| 25 | + </PropertyGroup> | |
| 26 | + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |
| 27 | + <PlatformTarget>AnyCPU</PlatformTarget> | |
| 28 | + <DebugType>pdbonly</DebugType> | |
| 29 | + <Optimize>true</Optimize> | |
| 30 | + <OutputPath>bin\Release\</OutputPath> | |
| 31 | + <DefineConstants>TRACE</DefineConstants> | |
| 32 | + <ErrorReport>prompt</ErrorReport> | |
| 33 | + <WarningLevel>4</WarningLevel> | |
| 34 | + </PropertyGroup> | |
| 35 | + <ItemGroup> | |
| 36 | + <Reference Include="System" /> | |
| 37 | + <Reference Include="System.Configuration.Install" /> | |
| 38 | + <Reference Include="System.Core" /> | |
| 39 | + <Reference Include="System.Management" /> | |
| 40 | + <Reference Include="System.Xml.Linq" /> | |
| 41 | + <Reference Include="System.Data.DataSetExtensions" /> | |
| 42 | + <Reference Include="Microsoft.CSharp" /> | |
| 43 | + <Reference Include="System.Data" /> | |
| 44 | + <Reference Include="System.Net.Http" /> | |
| 45 | + <Reference Include="System.ServiceProcess" /> | |
| 46 | + <Reference Include="System.Xml" /> | |
| 47 | + </ItemGroup> | |
| 48 | + <ItemGroup> | |
| 49 | + <Compile Include="ProjectInstaller.cs"> | |
| 50 | + <SubType>Component</SubType> | |
| 51 | + </Compile> | |
| 52 | + <Compile Include="ProjectInstaller.Designer.cs"> | |
| 53 | + <DependentUpon>ProjectInstaller.cs</DependentUpon> | |
| 54 | + </Compile> | |
| 55 | + <Compile Include="Service1.cs"> | |
| 56 | + <SubType>Component</SubType> | |
| 57 | + </Compile> | |
| 58 | + <Compile Include="Service1.Designer.cs"> | |
| 59 | + <DependentUpon>Service1.cs</DependentUpon> | |
| 60 | + </Compile> | |
| 61 | + <Compile Include="Program.cs" /> | |
| 62 | + <Compile Include="Properties\AssemblyInfo.cs" /> | |
| 63 | + </ItemGroup> | |
| 64 | + <ItemGroup> | |
| 65 | + <None Include="App.config" /> | |
| 66 | + </ItemGroup> | |
| 67 | + <ItemGroup> | |
| 68 | + <EmbeddedResource Include="ProjectInstaller.resx"> | |
| 69 | + <DependentUpon>ProjectInstaller.cs</DependentUpon> | |
| 70 | + </EmbeddedResource> | |
| 71 | + </ItemGroup> | |
| 72 | + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |
| 73 | +</Project> | |
| 0 | 74 | \ No newline at end of file | ... | ... |