Commit fc8a064bd0ba4c7cb27b77d712cc17e61dd82695

Authored by Schwirg László
1 parent 0e9c5d3a

v1.27.0

- MoveDbToRemoteServer megvalósítása
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs
... ... @@ -301,10 +301,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS
301 301 public static class BackupDataBase { public const string KEY = "BAK"; }
302 302 public static class CreateCodeScripts { public const string KEY = "CCS"; }
303 303 public static class CreateDataScripts { public const string KEY = "CDS"; }
304   - public static class RestoreDataBase { public const string KEY = "RES"; public const string CMD_RESTOREFIRST = "-RESTOREFIRST";
305   - }
  304 + public static class RestoreDataBase { public const string KEY = "RES"; public const string KEY2 = "RE2"; public const string CMD_RESTOREFIRST = "-RESTOREFIRST";}
  305 + public static class MoveDbToRemoteServer { public const string KEY = "MOV"; }
306 306 public static class RelocatePhysicalFiles { public const string KEY = "COP"; }
307 307 public static class ShrinkDB { public const string KEY = "SHR"; }
  308 + public static class DropDB { public const string KEY = "DRP";}
308 309 public static class ExecuteScript{ public const string KEY = "EXE"; }
309 310 public static class CreateLoginAndUser{ public const string KEY = "CRU"; }
310 311 public static class AddUserForLogin{ public const string KEY = "CRA"; }
... ...
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - Menu.cs
... ... @@ -16,6 +16,7 @@ using Vrh.XmlProcessing;
16 16 using VRH.Common;
17 17 using System.Xml.Linq;
18 18 using System.Reflection;
  19 +using Vrh.Log4Pro.MaintenanceConsole.ToolsNS;
19 20  
20 21 namespace Vrh.Log4Pro.MaintenanceConsole.MenuNS
21 22 {
... ... @@ -168,8 +169,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MenuNS
168 169 }
169 170 catch (Exception ex)
170 171 {
171   - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);
172   - if (ex.InnerException != null) { ColorConsole.WriteLine(ex.InnerException.Message, ConsoleColor.Red); }
  172 + ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red);
173 173 Menu.PressAnykeyToContinue();
174 174 }
175 175 }
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - FileCleanerManager.cs
... ... @@ -75,7 +75,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.FileCleanerManagerNS
75 75 var success = FileCleanerManagerCore.CleanFolderFiles(di, ftc, delete: true);
76 76 ColorConsole.WriteLine($"Folder cleaned. Name:{ftc.Xml_DirectoryPath}", ConsoleColor.Green);
77 77 }
78   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  78 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
79 79 }
80 80 #endregion First level Executors with UI
81 81  
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - MSMQManager.cs
... ... @@ -83,7 +83,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
83 83 ColorConsole.WriteLine($"Access right {accessright.ar} {ctrlstring} for user:{accessright.un}.", ConsoleColor.Green);
84 84 }
85 85 }
86   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  86 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
87 87 }
88 88 return o;
89 89 }
... ... @@ -111,7 +111,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
111 111 MSMQManagerCore.DeleteQueue(fullpath);
112 112 ColorConsole.WriteLine($"MSMQ:{st.Xml_Name} removed.", ConsoleColor.Green);
113 113 }
114   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  114 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
115 115 }
116 116 return o;
117 117 }
... ... @@ -145,7 +145,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
145 145 ColorConsole.WriteLine($"Access right {accessright.ar} {ctrlstring} for user:{accessright.un}.", ConsoleColor.Green);
146 146 }
147 147 }
148   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  148 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
149 149 }
150 150 return o;
151 151 }
... ... @@ -192,7 +192,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
192 192 MSMQManagerCore.SetPermissions(fullpath, username, accessrights, controltype);
193 193 ColorConsole.WriteLine($"Permissions set for MSMQ:{st.Xml_Name}. Username:{username}, access right: {accessrights}, control type: {controltype}", ConsoleColor.Green);
194 194 }
195   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  195 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
196 196 }
197 197  
198 198 defaultusername = username;
... ... @@ -320,10 +320,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
320 320 ColorConsole.WriteLine($" Body: {msgbody}", ConsoleColor.Yellow);
321 321 ColorConsole.WriteLine($" Label: {msglabel}", ConsoleColor.Yellow);
322 322 }
323   - catch (Exception ex)
324   - {
325   - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);
326   - }
  323 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
327 324 }
328 325 return o;
329 326 }
... ... @@ -356,10 +353,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
356 353 ColorConsole.WriteLine($" Body: {msgbody}", ConsoleColor.Yellow);
357 354 ColorConsole.WriteLine($" Label: {msglabel}", ConsoleColor.Yellow);
358 355 }
359   - catch (Exception ex)
360   - {
361   - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);
362   - }
  356 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
363 357 }
364 358 return o;
365 359 }
... ... @@ -395,8 +389,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
395 389 ColorConsole.WriteLine($"Message sent to MSMQ:{st.Xml_Name}.", ConsoleColor.Green);
396 390 }
397 391 }
398   - catch (ApplicationException ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
399   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  392 + catch (ApplicationException ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
  393 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
400 394 }
401 395 }
402 396 return o;
... ... @@ -514,7 +508,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
514 508 MSMQManagerCore.Purge(fullpath);
515 509 ColorConsole.WriteLine($"MSMQ messages purged. Name:{st.Xml_Name}", ConsoleColor.Green);
516 510 }
517   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  511 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
518 512 }
519 513 return o;
520 514 }
... ... @@ -1118,7 +1112,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
1118 1112 }
1119 1113 catch (MessageQueueException ex)
1120 1114 {
1121   - returnmessage= ex.ErrorCode + ":" + ex.Message + (ex.InnerException != null ? ("\n" + ex.InnerException.Message) : "");
  1115 + returnmessage= ex.ErrorCode + ":" + ex.MessageNested();
1122 1116 return ex.Message.StartsWith("Timeout");
1123 1117 }
1124 1118 }
... ... @@ -1167,11 +1161,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
1167 1161 }
1168 1162 catch (MessageQueueException ex)
1169 1163 {
1170   - msmqdef.Status = "Error"; msmqdef.StatusDescription = ex.ErrorCode +":"+ ex.Message + (ex.InnerException != null ? ("\n" + ex.InnerException.Message) : "");
  1164 + msmqdef.Status = "Error"; msmqdef.StatusDescription = ex.ErrorCode +":"+ ex.MessageNested();
1171 1165 }
1172 1166 catch (Exception ex)
1173 1167 {
1174   - msmqdef.Status = "Error"; msmqdef.StatusDescription = ex.Message + (ex.InnerException != null ? ("\n" + ex.InnerException.Message) : "");
  1168 + msmqdef.Status = "Error"; msmqdef.StatusDescription = ex.MessageNested();
1175 1169 }
1176 1170 return msmqdef;
1177 1171 }
... ... @@ -1350,7 +1344,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MSMQManagerNS
1350 1344 ColorConsole.WriteLine();
1351 1345 }
1352 1346 }
1353   - catch (Exception ex) { ColorConsole.WriteLine(" " + ex.Message, ConsoleColor.Red); }
  1347 + catch (Exception ex) { ColorConsole.WriteLine(" " + ex.MessageNested(), ConsoleColor.Red); }
1354 1348 }
1355 1349 }
1356 1350 #endregion DisplayInfo
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - MaintenanceToolManager.cs
... ... @@ -532,7 +532,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.MaintenanceToolManagerNS
532 532 }
533 533 catch (Exception ex)
534 534 {
535   - ColorConsole.WriteLine(ex.Message, f: ConsoleColor.Red);
  535 + ColorConsole.WriteLine(ex.MessageNested(), f: ConsoleColor.Red);
536 536 return false;
537 537 }
538 538 }
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - SQLDataBaseManager.cs
... ... @@ -25,7 +25,7 @@ using System.Text.RegularExpressions;
25 25  
26 26 using Microsoft.SqlServer.Management.Common;
27 27 using Microsoft.SqlServer.Management.Smo;
28   -using System.Data.SqlClient;
  28 +using Microsoft.Data.SqlClient;
29 29  
30 30 namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
31 31 {
... ... @@ -48,12 +48,15 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
48 48 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateCodeScripts.KEY, "Create code scripts", CreateCodeScripts, ep))
49 49 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateDataScripts.KEY, "Create data scripts", CreateDataScripts, ep))
50 50 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RestoreDataBase.KEY, "Restore database backup", RestoreDataBase, ep))
  51 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RestoreDataBase.KEY2, "Restore database backup (any to anywhere)", RestoreDataBaseAnyToAnywhere, ep))
51 52 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.RelocatePhysicalFiles.KEY, "Copy database and or relocate its physical files", RelocatePhysicalFiles, ep))
52 53 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ShrinkDB.KEY, "Shrink database", ShrinkDB, ep))
  54 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.DropDB.KEY, "Drop database", DropDB, ep))
53 55 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.ExecuteScript.KEY, "Execute script", ExecuteScript, ep))
54   - .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateLoginAndUser.KEY, "Create Server login and database user", CreteLoginAndAddToDB, ep))
55   - .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.AddUserForLogin.KEY, "Add database user to an existing Login", AddExistingLoginToDB, ep))
  56 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateLoginAndUser.KEY, "Create Server login", CreateServerLogin, ep))
  57 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.AddUserForLogin.KEY, "Create DB user", CreateDBUser, ep))
56 58 .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.CreateLastUpdatedTrigger.KEY, "Add/remove LastUpdated trigger to a datatable column", ManageLastUpdatedTrigger, ep))
  59 + .AddMenuItem(new Menu.Item(CLP.Module.SQLDataBaseManager.Function.MoveDbToRemoteServer.KEY, "Move DB from local to remote server", MoveDbToRemoteServer, ep))
57 60 .SetSelectionMode(Menu.SelectionMode.Single)
58 61 .SetMenuHeaderDisplayer(DataBaseListDisplayer);
59 62 menufunctions.ExecuteMenu(functionkey);
... ... @@ -105,10 +108,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
105 108 SQLDataBaseManagerCore.BackupSqlData(sqld,TS);
106 109 ColorConsole.WriteLine($"SQLDB data scripts created. Name:{sqld.Xml_Description}", ConsoleColor.Green);
107 110 }
108   - catch (Exception ex)
109   - {
110   - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);
111   - }
  111 + catch (Exception ex){ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red);}
112 112 }
113 113 return o;
114 114 }
... ... @@ -138,7 +138,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
138 138 SQLDataBaseManagerCore.BackupSqlScripts(sqld,TS);
139 139 ColorConsole.WriteLine($"SQLDB code scripts created. Name:{sqld.Xml_Description}", ConsoleColor.Green);
140 140 }
141   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  141 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
142 142 }
143 143 return o;
144 144 }
... ... @@ -167,7 +167,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
167 167 SQLDataBaseManagerCore.CreateBackup(ssqldb,null,TS);
168 168 ColorConsole.WriteLine($"Database backup created. Name:{ssqldb.DBName}", ConsoleColor.Green);
169 169 }
170   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  170 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
171 171 }
172 172 return o;
173 173 }
... ... @@ -179,53 +179,335 @@ namespace Vrh.Log4Pro.MaintenanceConsole.SQLDataBaseManagerNS
179 179 var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES);
180 180 bool restorefirst = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.RestoreDataBase.CMD_RESTOREFIRST,switchtype:true)!=null;
181 181  
182   - var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{nameof(RestoreDataBase)}'!", silent: true);
  182 + startselection:
  183 + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{nameof(RestoreDataBase)}'!", silent: true,selectionmode:Menu.SelectionMode.Single);
183 184  
184 185 Menu.Selection sr = menufolders.Select(selectedsqldbindexes);
185 186 if (sr.Result == Menu.SelectionResult.Exit) { return o; }
186 187 else if (sr.Result == Menu.SelectionResult.None) { return o; }
187 188 else if (sr.Result == Menu.SelectionResult.Error) { return o; }
  189 + else if (sr.Result == Menu.SelectionResult.Ok && sr.SelectedParameterList.FirstOrDefault() == null) { return o; }
188 190 else if (sr.Result == Menu.SelectionResult.Ok) { }
189 191 else { }
190   - foreach (var p in sr.SelectedParameterList)
  192 + var p = sr.SelectedParameterList.First();
  193 + SQLDataBase st = p.Parameters as SQLDataBase;
  194 + try
191 195 {
192   - SQLDataBase st = p.Parameters as SQLDataBase;
193   - try
  196 + var targetdirectorypath = st.Xml_PhysicalFilesDirectoryPath;
  197 + var targetdbname = st.DBName;
  198 + bool restorefromzip = st.Xml_CreateZip;
  199 + var backupfilelist = SQLDataBaseManagerCore.GetBackupFilePathList(st);
  200 + Dictionary<string, string> selectionlist = new Dictionary<string, string>();
  201 +
  202 + string selectedbackupfilepath=null;
  203 + if (backupfilelist == null || !backupfilelist.Any()) { }
  204 + else if (restorefirst) { selectedbackupfilepath = backupfilelist.First().FullName; }
  205 + else
194 206 {
195   - var targetdirectorypath = st.Xml_PhysicalFilesDirectoryPath;
196   - var targetdbname= st.DBName;
197   - bool restorefromzip = st.Xml_CreateZip;
198   - var backupfilelist = SQLDataBaseManagerCore.GetBackupFilePathList(st);
199   - if (backupfilelist != null && backupfilelist.Any())
200   - {
201   - string selectedbackupfilepath;
202   - if (restorefirst)
203   - {
204   - selectedbackupfilepath = backupfilelist.First().FullName;
205   - }
206   - else
207   - {
208   - var selectionlist = backupfilelist
209   - .Select(x => new KeyValuePair<string,string>($"{x.Name}({x.Length}bytes,created:{x.CreationTime})", x.FullName))
210   - .ToDictionary(x=>x.Key,x=>x.Value);
211   - var ms = Menu.SelectFromItemList($"Backup files of {st.DBName}", "Select the backup file to restore! First is the newest!", selectionlist,Menu.SelectionMode.Single,getconfirmation:true);
212   - if (ms == null) { continue; }
213   - selectedbackupfilepath = ms.SelectedParameterList.First().Parameters.ToString();
214   - }
215   - SQLDataBaseManagerCore.RestoreBackup(st, selectedbackupfilepath, targetdirectorypath, restorefromzip, targetdbname);
216   - ColorConsole.WriteLine($"Database '{st.DBName}' restored to '{targetdbname}' into directory '{targetdirectorypath}'.", ConsoleColor.Green);
217   - }
218   - else
219   - {
220   - ColorConsole.WriteLine($"Database '{st.DBName}' restore FAILED, as no backup to restore!", ConsoleColor.Red);
221   - }
  207 + selectionlist = (backupfilelist??new List<FileInfo>())
  208 + .Select(x => new KeyValuePair<string, string>($"{x.Name}({x.Length}bytes,created:{x.CreationTime})", x.FullName))
  209 + .ToDictionary(x => x.Key, x => x.Value);
  210 + selectionlist.Add("*", "other...");
  211 + var ms = Menu.SelectFromItemList($"Backup files of {st.DBName}", "Select the backup file to restore! First is the newest!", selectionlist, Menu.SelectionMode.Single, getconfirmation: true);
  212 + if (ms == null) { goto startselection; }
  213 + else if (ms.SelectedKeyList.First() == "*") { }
  214 + else { selectedbackupfilepath = ms.SelectedParameterList.First().Parameters.ToString(); }
  215 + }
  216 + if (selectedbackupfilepath == null)
  217 + {
  218 + enterpathtobackupfileloop:
  219 + selectedbackupfilepath = ColorConsole.ReadLine("Enter the full path to the backup file, EX: to exit", ConsoleColor.Yellow);
  220 + if (selectedbackupfilepath.ToUpper() == "EX") return o;
  221 + else if (string.IsNullOrWhiteSpace(selectedbackupfilepath)) goto enterpathtobackupfileloop;
222 222 }
223   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  223 +
  224 + SQLDataBaseManagerCore.RestoreBackup(st, selectedbackupfilepath, targetdirectorypath, restorefromzip, targetdbname);
  225 + ColorConsole.WriteLine($"Database '{st.DBName}' restored to '{targetdbname}' into directory '{targetdirectorypath}'.", ConsoleColor.Green);
  226 + }
  227 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
  228 + return o;
  229 + }
  230 + private static object RestoreDataBaseAnyToAnywhere(object parameter, object o)
  231 + {
  232 + var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
  233 + var args = (parameter as Menu.ExecutorParameter).Args;
  234 +
  235 + var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES);
  236 + bool restorefirst = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.RestoreDataBase.CMD_RESTOREFIRST, switchtype: true) != null;
  237 +
  238 + startselection:
  239 + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{nameof(RestoreDataBaseAnyToAnywhere)}'!", silent: true, selectionmode: Menu.SelectionMode.Single);
  240 +
  241 + Menu.Selection sr = menufolders.Select(selectedsqldbindexes);
  242 + if (sr.Result == Menu.SelectionResult.Exit) { return o; }
  243 + else if (sr.Result == Menu.SelectionResult.None) { return o; }
  244 + else if (sr.Result == Menu.SelectionResult.Error) { return o; }
  245 + else if (sr.Result == Menu.SelectionResult.Ok && sr.SelectedParameterList.FirstOrDefault() == null) { return o; }
  246 + else if (sr.Result == Menu.SelectionResult.Ok) { }
  247 + else { }
  248 + var p = sr.SelectedParameterList.First();
  249 + SQLDataBase st = p.Parameters as SQLDataBase;
  250 + try
  251 + {
  252 + var selectedbackupfilepath = ColorConsole.ReadLine("Enter the full path to the backup file (or its zip), EX: to exit", ConsoleColor.Yellow);
  253 + if (selectedbackupfilepath.ToUpper() == "EX") { return o; }
  254 + if (string.IsNullOrWhiteSpace(selectedbackupfilepath)) { goto startselection; }
  255 + var targetdirectorypath = ColorConsole.ReadLine("Enter the full path to the folder where the DB physical files will be located, EX: to exit", ConsoleColor.Yellow);
  256 + if (targetdirectorypath.ToUpper() == "EX") { return o; }
  257 + if (string.IsNullOrWhiteSpace(selectedbackupfilepath)) { goto startselection; }
  258 + var targetdbname = ColorConsole.ReadLine($"Enter the name of the target DB (empty={st.DBName}), EX: to exit", ConsoleColor.Yellow);
  259 + if (targetdirectorypath.ToUpper() == "EX") { return o; }
  260 + if (string.IsNullOrWhiteSpace(selectedbackupfilepath)) { targetdbname = st.DBName; }
  261 + bool restorefromzip =Path.GetExtension(selectedbackupfilepath).ToLower() == ".zip"; ;
  262 + SQLDataBaseManagerCore.RestoreBackup(st, selectedbackupfilepath, targetdirectorypath, restorefromzip, targetdbname);
  263 + ColorConsole.WriteLine($"Database '{targetdbname}' restored into directory '{targetdirectorypath}'.", ConsoleColor.Green);
  264 + goto startselection;
224 265 }
  266 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
  267 + return o;
  268 + }
  269 + private static object CreateServerLogin(object parameter, object o)
  270 + {
  271 + var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
  272 + var args = (parameter as Menu.ExecutorParameter).Args;
  273 + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS);
  274 + var menuofdbs = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{nameof(CreateServerLogin)}'!", silent: true, selectionmode: Menu.SelectionMode.Single);
  275 + Menu.Selection sr = menuofdbs.Select(selectedtaskindexes);
  276 + if (sr.Result == Menu.SelectionResult.Exit) { return o; }
  277 + else if (sr.Result == Menu.SelectionResult.None) { return o; }
  278 + else if (sr.Result == Menu.SelectionResult.Error) { return o; }
  279 + else if (sr.SelectedParameterList?.FirstOrDefault() == null) { return o; }
  280 + else if (sr.Result == Menu.SelectionResult.Ok) { }
  281 + else { }
  282 + string dbusername;
  283 + string password;
  284 + LoginType logintype;
  285 +
  286 + var p = sr.SelectedParameterList.FirstOrDefault();
  287 + SQLDataBase sqld = p.Parameters as SQLDataBase;
  288 +
  289 + parameterinputloop:
  290 + try
  291 + {
  292 + ColorConsole.WriteLine(prefix: $"Enter the parameters for creating server login: {sqld.DBName}. Format:", bracket: "()", text: "LOGINNAME[,PASSWORD][GRANTORUSER[,GRANTORUSERPASSWORD]]", f: ConsoleColor.Yellow);
  293 + ColorConsole.WriteLine(prefix: " ", text: "LOGINNAME", bracket: "", suffix: $": server login name");
  294 + ColorConsole.WriteLine(prefix: " ", text: "PASSWORD", bracket: "", suffix: $": password for login; empty=windows login is created, non empty=sql login is created");
  295 + ColorConsole.WriteLine(prefix: " ", text: "GRANTORUSER", bracket: "", suffix: $": name of the user in behalf the login is created (that logs in the sql server); default:current user with windows authentication");
  296 + ColorConsole.WriteLine(prefix: " ", text: "GRANTORUSERPASSWORD", bracket: "", suffix: $": password for GRANTORUSER;default:empy (windows authentication is used with GRANTORUSER)");
  297 +
  298 + var createuseroptions = ColorConsole.ReadLine($"EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
  299 + if (createuseroptions.ToUpper() == "EX") { return o; }
  300 +
  301 + dbusername = null;
  302 + password = null;
  303 + logintype = LoginType.WindowsUser;
  304 +
  305 + var optionList = createuseroptions.Split(new char[] { ',' }, StringSplitOptions.None);
  306 + if (optionList.Length < 1) { ColorConsole.WriteLine("ERROR! LOGINNAME is required, PASSWORD is optional", ConsoleColor.Red); goto parameterinputloop; }
  307 +
  308 + dbusername = optionList[0];
  309 + if (optionList.Length == 2)
  310 + {
  311 + password = optionList[1];
  312 + if (string.IsNullOrWhiteSpace(password)) { ColorConsole.WriteLine("ERROR! PASSWORD, if set, may not be empty!", ConsoleColor.Red); goto parameterinputloop; }
  313 + logintype = LoginType.SqlLogin;
  314 + }
  315 + string grantoruser = null;
  316 + string grantoruserpsw = null;
  317 + if (optionList.Length > 2)
  318 + {
  319 + grantoruser = optionList[2];
  320 + if (string.IsNullOrWhiteSpace(grantoruser)) { ColorConsole.WriteLine("ERROR! GRANTORUSER, if set, may not be empty!", ConsoleColor.Red); goto parameterinputloop; }
  321 + }
  322 + if (optionList.Length > 3)
  323 + {
  324 + grantoruserpsw = optionList[3];
  325 + if (string.IsNullOrWhiteSpace(grantoruser)) { ColorConsole.WriteLine("ERROR! GRANTORUSERPASSWORD, if set, may not be empty!", ConsoleColor.Red); goto parameterinputloop; }
  326 + }
  327 +
  328 + SQLDataBaseManagerCore.CreateLogin(sqld.SQLCS, dbusername, password, "master", logintype, null,grantoruser,grantoruserpsw);
  329 + string passwordtext = logintype == LoginType.WindowsUser ? "" : $", password:{password}";
  330 + ColorConsole.WriteLine($"Server login created. Server login name:{dbusername}, login type: {logintype}{passwordtext}.", ConsoleColor.Green);
  331 + }
  332 + catch (Exception ex)
  333 + {
  334 + ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red);
  335 + goto parameterinputloop;
  336 + }
  337 + goto parameterinputloop;
  338 +
  339 + }
  340 + private static string[] selectablerolelist = new string[] { "FULLACCESS", "DATAREADER", "db_accessadmin", "db_backupoperator", "db_datareader", "db_datawriter", "db_ddladmin", "db_denydatareader", "db_denydatawriter", "db_owner", "db_securityadmin", };
  341 + private static string[] fullaccessrolelist = new string[] { "db_accessadmin", "db_backupoperator", "db_datareader", "db_datawriter", "db_ddladmin", "db_owner", "db_securityadmin", };
  342 + private static string[] datareaderrolelist = new string[] { "db_datareader", "db_denydatareader", };
  343 + private static object CreateDBUser(object parameter, object o)
  344 + {
  345 + const string COMMA = ",";
  346 + var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
  347 + var args = (parameter as Menu.ExecutorParameter).Args;
  348 + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS);
  349 + var menuofdbs = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{nameof(CreateDBUser)}'!", silent: true, selectionmode: Menu.SelectionMode.Single);
  350 + Menu.Selection sr = menuofdbs.Select(selectedtaskindexes);
  351 + if (sr.Result == Menu.SelectionResult.Exit) { return o; }
  352 + else if (sr.Result == Menu.SelectionResult.None) { return o; }
  353 + else if (sr.Result == Menu.SelectionResult.Error) { return o; }
  354 + else if (sr.SelectedParameterList?.FirstOrDefault() == null) { return o; }
  355 + else if (sr.Result == Menu.SelectionResult.Ok) { }
  356 + else { }
  357 + string dbusername = null;
  358 + string loginname = null;
  359 + string rolenamecommalist = null;
  360 +
  361 + var p = sr.SelectedParameterList.FirstOrDefault();
  362 + SQLDataBase sqld = p.Parameters as SQLDataBase;
  363 +
  364 + parameterinputloop:
  365 + try
  366 + {
  367 + ColorConsole.WriteLine(prefix: $"Enter the parameters for creating DB user for: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,SERVERLOGINNAME,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow);
  368 + ColorConsole.WriteLine(prefix: " ", text: "DBUSERNAME", bracket: "", suffix: $": dbusername.");
  369 + ColorConsole.WriteLine(prefix: " ", text: "SERVERLOGINNAME", bracket: "", suffix: $": serverlogin name; empty=SQL user w/o login,w=WIndows user, other=SQL user for this server login name(* means server login name equals to dbusername).");
  370 + ColorConsole.WriteLine(prefix: " ", text: "ROLENAME", bracket: "", suffix: $": One of these->" + string.Join(COMMA, selectablerolelist));
  371 +
  372 + var createuseroptions = ColorConsole.ReadLine($"EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
  373 + if (createuseroptions.ToUpper() == "EX") { return o; }
  374 +
  375 + dbusername = null;
  376 + loginname = null;
  377 + rolenamecommalist = null;
  378 + var optionList = createuseroptions.Split(new char[] { ',' }, StringSplitOptions.None);
  379 + if (optionList.Length < 3) { ColorConsole.WriteLine("ERROR! DBUSERNAME,SERVERLOGINNAME and at least one ROLENAME are required", ConsoleColor.Red); goto parameterinputloop; }
  380 + //012345678
  381 + //uuu,ppp,r1,r2,r3
  382 + dbusername = optionList[0];
  383 + loginname = optionList[1];
  384 + var selectedrolelist = optionList.Skip(2).ToArray();
  385 + List<string> badrolenames = new List<string>();
  386 + bool enablefullaccess = false;
  387 + bool enabledatareader = false;
  388 + int selectedrolelistnum = 0;
  389 + foreach (var rolename in selectedrolelist)
  390 + {
  391 + selectedrolelistnum++;
  392 + enablefullaccess = enablefullaccess || rolename.ToUpper() == "FULLACCESS";
  393 + enabledatareader = enabledatareader || rolename.ToUpper() == "DATAREADER";
  394 + if (!selectablerolelist.Contains(rolename)) { badrolenames.Add(rolename); }
  395 + }
  396 + bool specialselectionactive = enablefullaccess || enabledatareader;
  397 + if (selectedrolelistnum > 1 && specialselectionactive) { ColorConsole.WriteLine($"ERROR! FULLACCESS or DATAREADER has to be selected alone!", ConsoleColor.Red); goto parameterinputloop; }
  398 + if (badrolenames.Count > 0) { ColorConsole.WriteLine($"ERROR! {string.Join(COMMA, badrolenames)} are not available!", ConsoleColor.Red); goto parameterinputloop; }
  399 +
  400 + var effectiverolelist =
  401 + enablefullaccess ? fullaccessrolelist
  402 + : enabledatareader ? datareaderrolelist
  403 + : selectedrolelist;
  404 + rolenamecommalist = string.Join(",", effectiverolelist);
  405 +
  406 + SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist, loginname);
  407 + ColorConsole.WriteLine($"DB user created. DB name:{sqld.DBName}, DB username:{dbusername}, rolelist={rolenamecommalist}.", ConsoleColor.Green);
  408 + }
  409 + catch (Exception ex)
  410 + {
  411 + ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red);
  412 + goto parameterinputloop;
  413 + }
  414 + goto parameterinputloop;
  415 + }
  416 + private static object MoveDbToRemoteServer(object parameter, object o)
  417 + {
  418 + var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
  419 + var args = (parameter as Menu.ExecutorParameter).Args;
  420 +
  421 + var selectedsqldbindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.SQLDataBaseManager.Function.CMD_DATABASES);
  422 +
  423 + selectionloop:
  424 + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function. '{nameof(MoveDbToRemoteServer)}'! Format:FROMLOCALDB,TOREMOTEDB", silent: true, selectionmode: Menu.SelectionMode.Multi);
  425 +
  426 + Menu.Selection sr = menufolders.Select(selectedsqldbindexes);
  427 + if (sr.Result == Menu.SelectionResult.Exit) { return o; }
  428 + else if (sr.Result == Menu.SelectionResult.None) { goto selectionloop; }
  429 + else if (sr.Result == Menu.SelectionResult.Error) { goto selectionloop; }
  430 + else if (sr.Result == Menu.SelectionResult.Ok && sr.SelectedParameterList.FirstOrDefault() == null) { goto selectionloop; }
  431 + else if (sr.Result == Menu.SelectionResult.Ok && sr.SelectedParameterList.Count() != 2)
  432 + {
  433 + ColorConsole.WriteLine($"Select exactly 2 DB. Format:FROMLOCALDB,TOREMOTEDB", ConsoleColor.Red);
  434 + goto selectionloop;
  435 + }
  436 + else if (sr.Result == Menu.SelectionResult.Ok) { }
  437 + else { }
  438 + var spfrom = sr.SelectedParameterList.First();
  439 + var spto = sr.SelectedParameterList.ElementAt(1);
  440 + SQLDataBase dbfrom = spfrom.Parameters as SQLDataBase;
  441 + SQLDataBase dbto = spto.Parameters as SQLDataBase;
  442 + if (!dbto.Xml_IsRemoteDB)
  443 + {
  444 + ColorConsole.WriteLine($"TOREMOTEDB '{dbto.SQLCS}' has to be remote!", ConsoleColor.Red);
  445 + goto selectionloop;
  446 + }
  447 + if (dbfrom.Xml_IsRemoteDB)
  448 + {
  449 + ColorConsole.WriteLine($"FROMLOCALDB '{dbfrom.SQLCS}' has to be local!", ConsoleColor.Red);
  450 + goto selectionloop;
  451 + }
  452 + bool emulation = false;
  453 +
  454 + var selecteddbname = ColorConsole.ReadLine($"Enter the name of the restored DB. EMPTY={dbto.DBName}, EX=exit.");
  455 + if (selecteddbname.ToUpper() == "EX") return o;
  456 + else if (string.IsNullOrWhiteSpace(selecteddbname)) selecteddbname=dbto.DBName;
  457 +
  458 + confirmloop:;
  459 + var selection = ColorConsole.ReadLine("Enter CONFIRM to start, EMU to emulate, EX to exit.");
  460 + if (selection.ToUpper() == "EX") return o;
  461 + else if (selection.ToUpper() == "EMU") emulation = true;
  462 + else if (selection.ToUpper() == "CONFIRM") { }
  463 + else goto confirmloop;
  464 +
  465 + var DateTimeNow = DateTime.Now;
  466 + var usernameList = new string[] { "corplear\\lschwirg", "corplear\\gen_vrhalmadmin", $"corplear\\{Program.ThisComputer.ComputerName}$" };
  467 + foreach (var username in usernameList)
  468 + {
  469 + ColorConsole.WriteLine(username, ConsoleColor.Yellow, prefix: nameof(SQLDataBaseManagerCore.CreateUser) + ":");
  470 + try { if (!emulation) SQLDataBaseManagerCore.CreateLogin(dbfrom.SQLCS, username, null, "master", LoginType.WindowsUser, null); }
  471 + catch (Exception ex) { ColorConsole.WriteLine(nameof(SQLDataBaseManagerCore.CreateLogin)+">>>: "+ex.MessageNested(), ConsoleColor.Red); }
  472 + try { if (!emulation) SQLDataBaseManagerCore.CreateUser(dbfrom.SQLCS, username, string.Join(",", fullaccessrolelist), "w"); }
  473 + catch (Exception ex) { ColorConsole.WriteLine(nameof(SQLDataBaseManagerCore.CreateUser) + "\n" + ex.MessageNested(), ConsoleColor.Red); }
  474 + }
  475 +
  476 + //backup dbfrom
  477 + var backupfileFullname = SQLDataBaseManagerCore.CreateBackup(dbfrom, false, DateTimeNow,emulation);
  478 + //move dbfrom to tranit area
  479 +
  480 + if (!emulation && !File.Exists(backupfileFullname)) { goto selectionloop; }
  481 +
  482 + string backupfileFilename = null;
  483 + string tranzitfileFullname = null;
  484 + try
  485 + {
  486 + backupfileFilename = Path.GetFileName(backupfileFullname);
  487 + tranzitfileFullname = Path.Combine(dbto.Xml_TranzitDirectoryPath, backupfileFilename);
  488 + ColorConsole.WriteLine($"Moving backup file {backupfileFullname} to tranzit location: {dbto.Xml_TranzitDirectoryPath}", ConsoleColor.Yellow);
  489 + if (!emulation)
  490 + {
  491 + if (File.Exists(tranzitfileFullname)) { File.Delete(tranzitfileFullname); }
  492 + File.Move(backupfileFullname, tranzitfileFullname);
  493 + ColorConsole.WriteLine($"...completed...", ConsoleColor.Yellow);
  494 + }
  495 + }
  496 + catch (Exception ex)
  497 + {
  498 + ColorConsole.WriteLine($"Moving file FAILED!", ConsoleColor.Red);
  499 + ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red);
  500 + goto selectionloop;
  501 + }
  502 + if (!emulation && !File.Exists(tranzitfileFullname)) { goto selectionloop; }
  503 +
  504 + //restore backup to dbto
  505 + tranzitfileFullname = Path.Combine(dbto.Xml_TranzitDirectoryPath, backupfileFilename);
  506 + SQLDataBaseManagerCore.RestoreBackup(dbto, tranzitfileFullname, dbto.Xml_PhysicalFilesDirectoryPath, false, selecteddbname, emulation);
  507 +
  508 + ColorConsole.WriteLine($"Moving DB to remote server completed. Required time: {(int)(DateTime.Now.Subtract(DateTimeNow).TotalSeconds)} seconds.",ConsoleColor.Green);
225 509 return o;
226 510 }
227   - private static object CreteLoginAndAddToDB(object parameter, object o) { return _CreteLoginAndUser(parameter, o, true); }
228   - private static object AddExistingLoginToDB(object parameter, object o) { return _CreteLoginAndUser(parameter, o, false); }
229 511  
230 512 private static object ManageLastUpdatedTrigger(object parameter, object o) { return _ManageLastUpdatedTrigger(parameter, o, null); }
231 513 #region script texts for _RemoveAndCreateLastUpdatedTrigger
... ... @@ -351,10 +633,10 @@ GO
351 633  
352 634 if (!Tools.ResolveArguments(parameters, RemoveLastUpdatedTrigger_Script, out ssScriptText)) { throw new ApplicationException(); }
353 635 try {SQLDataBaseManagerCore.ExecuteSQLScript(sqld.SQLCS, ssScriptText, 5000, null); }
354   - catch (Exception e) {ColorConsole.WriteLine(e.Message, ConsoleColor.Yellow);}
  636 + catch (Exception e) {ColorConsole.WriteLine(e.MessageNested(), ConsoleColor.Yellow);}
355 637 if (!Tools.ResolveArguments(parameters, RemoveLastUpdatedColumn_Script, out ssScriptText)) { throw new ApplicationException(); }
356 638 try {SQLDataBaseManagerCore.ExecuteSQLScript(sqld.SQLCS, ssScriptText, 5000, null);}
357   - catch (Exception e) { ColorConsole.WriteLine(e.Message, ConsoleColor.Yellow); }
  639 + catch (Exception e) { ColorConsole.WriteLine(e.MessageNested(), ConsoleColor.Yellow); }
358 640  
359 641 if (!effectiveremoveaction)
360 642 {
... ... @@ -377,102 +659,10 @@ GO
377 659 }
378 660 catch (Exception e)
379 661 {
380   - ColorConsole.WriteLine("FATAL ERROR! "+e.Message, ConsoleColor.Red);
  662 + ColorConsole.WriteLine("FATAL ERROR! "+e.MessageNested(), ConsoleColor.Red);
381 663 goto getparameters;
382 664 }
383 665 }
384   - private static object _CreteLoginAndUser(object parameter, object o,bool createlogin)
385   - {
386   - const string COMMA = ",";
387   - var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
388   - var args = (parameter as Menu.ExecutorParameter).Args;
389   - var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS);
390   - var functionname = createlogin ? nameof(CreteLoginAndAddToDB) : nameof(AddExistingLoginToDB);
391   - var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) to manage with function '{functionname}'!", silent: true);
392   - Menu.Selection sr = menufolders.Select(selectedtaskindexes);
393   - if (sr.Result == Menu.SelectionResult.Exit) { return o; }
394   - else if (sr.Result == Menu.SelectionResult.None) { return o; }
395   - else if (sr.Result == Menu.SelectionResult.Error) { return o; }
396   - else if (sr.Result == Menu.SelectionResult.Ok) { }
397   - else { }
398   - string dbusername = null;
399   - string password = null;
400   - string rolenamecommalist = null;
401   - int loopindex = 0;
402   - bool effectivecreatelogin = createlogin;
403   - foreach (var p in sr.SelectedParameterList)
404   - {
405   - effectivecreatelogin = createlogin && loopindex == 0;
406   - SQLDataBase sqld = p.Parameters as SQLDataBase;
407   - try
408   - {
409   - var enabledrolelist = new string[] { "db_datareader", "db_datawriter", "db_accessadmin", "db_securityadmin", "db_backupoperator" };
410   - if (effectivecreatelogin)
411   - {
412   - ColorConsole.WriteLine(prefix: $"Enter the parameters for creating user for database: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,PASSWORD,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow);
413   - }
414   - else
415   - {
416   - ColorConsole.WriteLine(prefix: $"Enter the parameters for creating user for database: {sqld.DBName}. Format:", bracket: "()", text: "DBUSERNAME,ROLENAME,ROLENAME,ROLENAME...", f: ConsoleColor.Yellow);
417   - if (createlogin)
418   - {
419   - ColorConsole.WriteLine(prefix: $"Press [Enter] to use parameters set in the previous loop.", bracket: "()", text: $"{dbusername},{rolenamecommalist}", f: ConsoleColor.Yellow);
420   - }
421   - }
422   - ColorConsole.WriteLine(prefix: " ", text: "DBUSERNAME", bracket: "", suffix: $": dbusername (server login name; must exist when adding login to DB)");
423   - if (effectivecreatelogin)
424   - {
425   - ColorConsole.WriteLine(prefix: " ", text: "PASSWORD", bracket: "", suffix: $": password for login");
426   - }
427   - ColorConsole.WriteLine(prefix: " ", text: "ROLENAME", bracket: "", suffix: $": One of these->" + string.Join(COMMA, enabledrolelist));
428   -
429   - var createuseroptions = ColorConsole.ReadLine($"EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
430   - if (createuseroptions.ToUpper() == "EX") { continue; }
431   - if (loopindex>0 && string.IsNullOrWhiteSpace(createuseroptions)) { createuseroptions = $"{dbusername},{rolenamecommalist}"; }
432   -
433   - dbusername = null;
434   - password = null;
435   - rolenamecommalist = null;
436   - var optionList = createuseroptions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
437   - if (effectivecreatelogin)
438   - {
439   - if (optionList.Length < 3) { ColorConsole.WriteLine("ERROR! USERNAME,PASSWORD and at least one ROLENAME are required", ConsoleColor.Red); continue; }
440   - }
441   - else
442   - {
443   - if (optionList.Length < 2) { ColorConsole.WriteLine("ERROR! USERNAME and at least one ROLENAME are required", ConsoleColor.Red); continue; }
444   - }
445   - //012345678
446   - //uuu,ppp,r1,r2,r3
447   - dbusername = optionList[0];
448   - password = effectivecreatelogin ? optionList[1]:null;
449   - //rolenamecommalist = cretauseroptions.Substring(username.Length + password.Length + 2);
450   - var rolenameList = optionList.Skip(effectivecreatelogin ? 2:1).ToArray();
451   - List<string> badrolenames = new List<string>();
452   - foreach (var rolename in rolenameList)
453   - {
454   - if (!enabledrolelist.Contains(rolename)) { badrolenames.Add(rolename); }
455   - }
456   - if (badrolenames.Count > 0) { ColorConsole.WriteLine($"ERROR! {string.Join(COMMA, badrolenames)} are not available!", ConsoleColor.Red); continue; }
457   - rolenamecommalist = string.Join(",", rolenameList);
458   -
459   - if (effectivecreatelogin)
460   - {
461   - SQLDataBaseManagerCore.CreateLogin(sqld.SQLCS, dbusername, password, "master", null);
462   - SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist);
463   - ColorConsole.WriteLine($"Login and DB users created. DB name:{sqld.DBName}, login and DB username:{dbusername}, password:{password},rolelist={rolenamecommalist}.", ConsoleColor.Green);
464   - }
465   - else
466   - {
467   - SQLDataBaseManagerCore.CreateUser(sqld.SQLCS, dbusername, rolenamecommalist);
468   - ColorConsole.WriteLine($"DB user created. DB name:{sqld.DBName}, DB username:{dbusername}, rolelist={rolenamecommalist}.", ConsoleColor.Green);
469   - }
470   - }
471   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);continue; }
472   - loopindex++;
473   - }
474   - return o;
475   - }
476 666  
477 667 private static object ExecuteScript(object parameter, object o)
478 668 {
... ... @@ -532,11 +722,66 @@ GO
532 722 }
533 723 }
534 724 }
535   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  725 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
536 726 }
537 727 return o;
538 728 }
539 729  
  730 + private static object DropDB(object parameter, object o)
  731 + {
  732 + var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
  733 + var args = (parameter as Menu.ExecutorParameter).Args;
  734 +
  735 + var selectedtaskindexes = CommandLine.GetCommandLineArgument(args, CLP.Module.ScheduledTaskManager.Function.CMD_TASKS);
  736 +
  737 + var menufolders = DisplaySQLDataBaseMenu(config, $"Select the SQL database(s) that is located on the server, where the DB to manage with function '{nameof(DropDB)}'!", silent: true);
  738 +
  739 + Menu.Selection sr = menufolders.Select(selectedtaskindexes);
  740 + if (sr.Result == Menu.SelectionResult.Exit) { return o; }
  741 + else if (sr.Result == Menu.SelectionResult.None) { return o; }
  742 + else if (sr.Result == Menu.SelectionResult.Error) { return o; }
  743 + else if (sr.Result == Menu.SelectionResult.Ok) { }
  744 + else { }
  745 + foreach (var p in sr.SelectedParameterList)
  746 + {
  747 + SQLDataBase sqld = p.Parameters as SQLDataBase;
  748 + try
  749 + {
  750 + ColorConsole.WriteLine(prefix: $"Enter the dbname, the userid/password (for the user in favour you want to drop the DB). Format:", bracket: "()", text: "[DBNAME][,USERNAME[,PASSWORD]]:", f: ConsoleColor.Yellow);
  751 + ColorConsole.WriteLine(prefix: " ", text: "[DBNAME]", bracket: "[]", suffix: $":name of the DB to delete, default:{sqld.DBName}", f: ConsoleColor.Yellow);
  752 + ColorConsole.WriteLine(prefix: " ", text: "[USERNAME,PASSWORD empty]", bracket: "[]", suffix: $":use windows authentication with current user", f: ConsoleColor.Yellow);
  753 + ColorConsole.WriteLine(prefix: " ", text: "USERNAME", bracket: "[]", suffix: $":use windows authentication with this user", f: ConsoleColor.Yellow);
  754 + ColorConsole.WriteLine(prefix: " ", text: "USERNAME,PASSWORD", bracket: "[]", suffix: $":use sql server authentication with this user and password.", f: ConsoleColor.Yellow);
  755 + var parameters = ColorConsole.ReadLine($"EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
  756 + if (parameters.ToUpper() == "EX") { continue; }
  757 +
  758 + string userid = null;
  759 + string password = null;
  760 + string dbname = null;
  761 + if (!string.IsNullOrWhiteSpace(parameters))
  762 + {
  763 + dbname = parameters.Split(new char[] { ',' })[0];
  764 + if (parameters.IndexOf(',') >= 1) { userid = parameters.Split(new char[] { ',' })[1]; }
  765 + if (parameters.IndexOf(',') >= 0) { password = parameters.Split(new char[] { ',' })[2]; }
  766 + }
  767 + if (string.IsNullOrWhiteSpace(dbname)) { dbname = sqld.DBName; }
  768 + ColorConsole.WriteLine($"Dropping DB...");
  769 + ColorConsole.WriteLine(prefix: " connection string to server:", text: sqld.SQLCS, bracket: "[]", f: ConsoleColor.Yellow);
  770 + ColorConsole.WriteLine(prefix: " DB name to drop:", text: dbname, bracket: "[]", f: ConsoleColor.Yellow);
  771 + ColorConsole.WriteLine(prefix: " userid:", text: userid ?? "-", bracket: "[]", f: ConsoleColor.Yellow);
  772 + ColorConsole.WriteLine(prefix: " user psw:", text: password ?? "-", bracket: "[]", f: ConsoleColor.Yellow);
  773 + var confirmation = ColorConsole.ReadLine($"Enter CONFIRM to execute. EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
  774 + if (confirmation.ToUpper() == "EX") { continue; }
  775 + else if (confirmation.ToUpper() != "CONFIRM") { continue; }
  776 +
  777 + var success = SQLDataBaseManagerCore.DropDatabase(sqld.SQLCS, dbname, userid, password);
  778 + if (success) { ColorConsole.WriteLine($"SUCCESS! Database dropped. Name:{dbname}", ConsoleColor.Green); }
  779 + else { ColorConsole.WriteLine($"FAILURE! Database is NOT dropped. Name:{dbname}", ConsoleColor.Red); }
  780 + }
  781 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
  782 + }
  783 + return o;
  784 + }
540 785 private static object ShrinkDB(object parameter, object o)
541 786 {
542 787 var config = (parameter as Menu.ExecutorParameter).GetConfig<SQLDataBaseManagerXmlProcessor>();
... ... @@ -576,7 +821,7 @@ GO
576 821 SQLDataBaseManagerCore.ShrinkDB(sqld.SQLCS, shrinkmethod, fspint);
577 822 ColorConsole.WriteLine($"Database shrinked. Name:{sqld.DBName}", ConsoleColor.Green);
578 823 }
579   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  824 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
580 825 }
581 826 return o;
582 827 }
... ... @@ -605,7 +850,7 @@ GO
605 850 else if (string.IsNullOrWhiteSpace(restoredbname)) { restoredbname = sqld.DBName; }
606 851 ColorConsole.WriteLine("Enter the path for the DB physical files.", ConsoleColor.Yellow);
607 852 ColorConsole.WriteLine(sqld.PhysicalFilesDirectoryPath, ConsoleColor.Yellow, prefix: $" Empty=current location of source DB: ", bracket: "[]");
608   - ColorConsole.WriteLine(SQLDataBaseManagerCore.GetServerDefaultPhysicalDATFileLocation(sqld.SQLCS), ConsoleColor.Yellow,prefix: $" DEFAULT= sql server default location.",bracket:"[]");
  853 + ColorConsole.WriteLine(SQLDataBaseManagerCore.GetServerDefaultPhysicalDATFileLocation(sqld.SQLCS)??"???", ConsoleColor.Yellow,prefix: $" DEFAULT= sql server default location.",bracket:"[]");
609 854 var targetdirectory = ColorConsole.ReadLine($"Enter the target path.EX=exit.", ConsoleColor.Yellow, suffix: " --> ");
610 855 if (targetdirectory.ToUpper() == "EX") { continue; }
611 856 else if (targetdirectory == "DEFAULT") { targetdirectory = null; ; }
... ... @@ -616,7 +861,7 @@ GO
616 861 SQLDataBaseManagerCore.RelocatePhysicalFiles(sqld, targetdirectory, restoredbname);
617 862 ColorConsole.WriteLine($"Database physical files relocated. Name:{sqld.DBName}", ConsoleColor.Green);
618 863 }
619   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  864 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
620 865 }
621 866 return o;
622 867 }
... ... @@ -655,6 +900,7 @@ GO
655 900 {
656 901 ColorConsole.Write(st.DBName, statuscolor, bracket: "[]", prefix: "Database ", suffix: ". ");
657 902 ColorConsole.Write(st.DataSource, statuscolor, bracket: "[]", prefix: "from server ", suffix: ". ");
  903 + if (st.Xml_IsRemoteDB) { ColorConsole.Write("REMOTE", ConsoleColor.Cyan, bracket: "[]", prefix: "", suffix: ""); }
658 904 }
659 905 ColorConsole.WriteLine();
660 906 return " ";
... ... @@ -709,8 +955,8 @@ GO
709 955 {
710 956 try
711 957 {
712   - sqld.Status = GetStatus(sqld.SQLCS);
713   - sqld.PhysicalFilesDirectoryPath = (GetPhysicalFilesLocation(sqld.SQLCS))??"";
  958 + sqld.PhysicalFilesDirectoryPath = (GetPhysicalFilesLocation(sqld.SQLCS)) ?? "";
  959 + sqld.Status = string.IsNullOrWhiteSpace(sqld.PhysicalFilesDirectoryPath)? SQLDBStatus.NoAccess: SQLDBStatus.OK;
714 960 sqld.DBName = GetDBName(sqld.SQLCS);
715 961 sqld.DataSource = GetDataSource(sqld.SQLCS);
716 962 sqld.SizeString = GetSize(sqld.SQLCS);
... ... @@ -734,61 +980,91 @@ GO
734 980 RestoreBackup(sqld, dbbackupfilepath, targetdirectory, false, restoredbname);
735 981 if (File.Exists(dbbackupfilepath)) { File.Delete(dbbackupfilepath); }
736 982 }
737   - public static void RestoreBackup(SQLDataBase sqldb, string sourcesqlbackupfilepath, string targetdbphysicalfilesdirectorypath, bool restorefromZIP = false, string restoretodbname = null)
  983 + /// <summary>
  984 + /// Restores database backup (zipped or normal)
  985 + /// </summary>
  986 + /// <param name="sqldb"></param>
  987 + /// <param name="sourcesqlbackupfilepath">source backup file</param>
  988 + /// <param name="targetdbphysicalfilesdirectorypath"></param>
  989 + /// <param name="restorefromZIP">true=sourcesqlbackupfilepath is a zip file</param>
  990 + /// <param name="restoretodbname"></param>
  991 + /// <param name="emulate"></param>
  992 + public static void RestoreBackup(SQLDataBase sqldb, string sourcesqlbackupfilepath, string targetdbphysicalfilesdirectorypath, bool restorefromZIP = false, string restoretodbname = null,bool emulate=false)
738 993 {
739   - if (sqldb.Xml_IsRemoteDB)
740   - {
741   - ColorConsole.WriteLine(text: $" {nameof(RestoreBackup)}: data restore is not available for remote SQL Servers! DBname:'{sqldb.DBName}'.", prefix: $"WARNING!", f: ConsoleColor.Yellow);
742   - return;
743   - }
  994 + string sqlcs = sqldb.SQLCS; //sqlcs = sqlcs.Replace("LearALM2", "master");
  995 + string zippedbackupfilepath = restorefromZIP? sourcesqlbackupfilepath:Path.Combine(Path.GetDirectoryName(sourcesqlbackupfilepath), Path.GetFileNameWithoutExtension(sourcesqlbackupfilepath) + ".zip");
  996 + string normalbackupfilepath = !restorefromZIP? sourcesqlbackupfilepath : Path.Combine(Path.GetDirectoryName(sourcesqlbackupfilepath), Path.GetFileNameWithoutExtension(sourcesqlbackupfilepath) + ".bak");
  997 +
  998 + ColorConsole.WriteLine(nameof(RestoreBackup), ConsoleColor.Yellow, prefix: "running....");
  999 + ColorConsole.WriteLine(restoretodbname, ConsoleColor.Yellow, prefix: " restoretodbname:");
  1000 + ColorConsole.WriteLine(sqldb.SQLCS, ConsoleColor.Yellow, prefix: " sqldb.SQLCS:");
  1001 + ColorConsole.WriteLine(sourcesqlbackupfilepath, ConsoleColor.Yellow, prefix: " sourcesqlbackupfilepath:");
  1002 + ColorConsole.WriteLine(normalbackupfilepath, ConsoleColor.Yellow, prefix: " backupfilepath:");
  1003 + ColorConsole.WriteLine(restorefromZIP.ToString(), ConsoleColor.Yellow, prefix: " restorefromZIP:");
  1004 + ColorConsole.WriteLine(zippedbackupfilepath, ConsoleColor.Yellow, prefix: " zippedbackupfilepath:");
  1005 + ColorConsole.WriteLine(targetdbphysicalfilesdirectorypath, ConsoleColor.Yellow, prefix: " targetdbphysicalfilesdirectorypath:");
  1006 + if (emulate) { return; }
744 1007  
745   - string sqlcs = sqldb.SQLCS;
746   - string backupfilepath;
747 1008 if (restorefromZIP)
748 1009 {
749   - backupfilepath = Path.Combine(Path.GetDirectoryName(sourcesqlbackupfilepath), Path.GetFileNameWithoutExtension(sourcesqlbackupfilepath) + ".bak");
750   - ZipTools.Extract1stFileFromZIP(backupfilepath, sourcesqlbackupfilepath);
  1010 + if (!File.Exists(zippedbackupfilepath))
  1011 + {
  1012 + ColorConsole.WriteLine($"ERROR! Restore source zipped backup file '{zippedbackupfilepath}' does not exist!", ConsoleColor.Red, prefix: "");
  1013 + return;
  1014 + }
  1015 + ZipTools.Extract1stFileFromZIP(normalbackupfilepath, zippedbackupfilepath);
751 1016 var starttime = DateTime.Now;
752   - while (DateTime.Now.Subtract(starttime).TotalSeconds > 5) { if (File.Exists(backupfilepath)) { break; } Thread.Sleep(500); }
753   - }
754   - else { backupfilepath = sourcesqlbackupfilepath; }
755   - var sqlserver = SQLServerConnect(sqlcs);
756   -
757   - var smoRestore = new Restore();
758   - smoRestore.NoRecovery = false;
759   - smoRestore.ReplaceDatabase = true;
760   - smoRestore.Action = RestoreActionType.Database;
761   - smoRestore.PercentCompleteNotification = 5;
762   - var backupdevice = new BackupDeviceItem(backupfilepath, DeviceType.File);
763   - smoRestore.Devices.Add(backupdevice);
764   - smoRestore.Database = string.IsNullOrWhiteSpace(restoretodbname)
765   - ? smoRestore.ReadBackupHeader(sqlserver).Rows[0]["DatabaseName"].ToString()
766   - : restoretodbname;
767   -
768   - var dbfilelist = smoRestore.ReadFileList(sqlserver);
769   - var smorestoreDATfile = new RelocateFile();
770   - string targetdbphysicalfilesdirectorypathDAT = targetdbphysicalfilesdirectorypath;
771   - if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathDAT)) { targetdbphysicalfilesdirectorypathDAT = sqlserver.DefaultFile; }
772   - if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathDAT)) { targetdbphysicalfilesdirectorypathDAT = sqlserver.MasterDBPath; }
773   - smorestoreDATfile.PhysicalFileName = Path.Combine(targetdbphysicalfilesdirectorypathDAT, smoRestore.Database + "_Data.mdf");
774   - smorestoreDATfile.LogicalFileName = dbfilelist.Select("Type='D'")[0]["LogicalName"].ToString();
775   - smoRestore.RelocateFiles.Add(smorestoreDATfile);
776   -
777   - var smorestoreLOGfile = new RelocateFile();
778   - string targetdbphysicalfilesdirectorypathLOG = targetdbphysicalfilesdirectorypath;
779   - if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathLOG)) { targetdbphysicalfilesdirectorypathLOG = sqlserver.DefaultLog; }
780   - if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathLOG)) { targetdbphysicalfilesdirectorypathLOG = sqlserver.MasterDBLogPath; }
781   - smorestoreLOGfile.PhysicalFileName = Path.Combine(targetdbphysicalfilesdirectorypathLOG, smoRestore.Database + "_Log.ldf");
782   - smorestoreLOGfile.LogicalFileName = dbfilelist.Select("Type='L'")[0]["LogicalName"].ToString();
783   - smoRestore.RelocateFiles.Add(smorestoreLOGfile);
784   -
785   - sqlserver.KillAllProcesses(smoRestore.Database);
786   -
787   - smoRestore.SqlRestore(sqlserver);
788   - if (restorefromZIP)
  1017 + while (DateTime.Now.Subtract(starttime).TotalSeconds > 5) { if (File.Exists(normalbackupfilepath)) { break; } Thread.Sleep(500); }
  1018 + }
  1019 +
  1020 + if (!File.Exists(normalbackupfilepath))
  1021 + {
  1022 + ColorConsole.WriteLine($"ERROR! Restore source backup file '{normalbackupfilepath}' does not exist!", ConsoleColor.Red, prefix: "");
  1023 + return;
  1024 + }
  1025 + Server sqlserver = null;
  1026 + try
789 1027 {
790   - if (File.Exists(backupfilepath)) { File.Delete(backupfilepath); }
  1028 + var sc = GetSqlConnection(sqlcs, "master");
  1029 + sqlserver = SQLServerConnect(sc);if (sqlserver == null) { return; }
  1030 +
  1031 + var smoRestore = new Restore();
  1032 + smoRestore.NoRecovery = false;
  1033 + smoRestore.ReplaceDatabase = true;
  1034 + smoRestore.Action = RestoreActionType.Database;
  1035 + smoRestore.PercentComplete += SmoBackupRestore_PercentComplete;
  1036 + smoRestore.PercentCompleteNotification = 1;
  1037 + var backupdevice = new BackupDeviceItem(normalbackupfilepath, DeviceType.File);
  1038 + smoRestore.Devices.Add(backupdevice);
  1039 + smoRestore.Database = string.IsNullOrWhiteSpace(restoretodbname)
  1040 + ? smoRestore.ReadBackupHeader(sqlserver).Rows[0]["DatabaseName"].ToString()
  1041 + : restoretodbname;
  1042 +
  1043 +
  1044 + var dbfilelist = smoRestore.ReadFileList(sqlserver);
  1045 + var smorestoreDATfile = new RelocateFile();
  1046 + string targetdbphysicalfilesdirectorypathDAT = targetdbphysicalfilesdirectorypath;
  1047 + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathDAT)) { targetdbphysicalfilesdirectorypathDAT = sqlserver.DefaultFile; }
  1048 + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathDAT)) { targetdbphysicalfilesdirectorypathDAT = sqlserver.MasterDBPath; }
  1049 + smorestoreDATfile.PhysicalFileName = Path.Combine(targetdbphysicalfilesdirectorypathDAT, smoRestore.Database + "_Data.mdf");
  1050 + smorestoreDATfile.LogicalFileName = dbfilelist.Select("Type='D'")[0]["LogicalName"].ToString();
  1051 + smoRestore.RelocateFiles.Add(smorestoreDATfile);
  1052 +
  1053 + var smorestoreLOGfile = new RelocateFile();
  1054 + string targetdbphysicalfilesdirectorypathLOG = targetdbphysicalfilesdirectorypath;
  1055 + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathLOG)) { targetdbphysicalfilesdirectorypathLOG = sqlserver.DefaultLog; }
  1056 + if (string.IsNullOrEmpty(targetdbphysicalfilesdirectorypathLOG)) { targetdbphysicalfilesdirectorypathLOG = sqlserver.MasterDBLogPath; }
  1057 + smorestoreLOGfile.PhysicalFileName = Path.Combine(targetdbphysicalfilesdirectorypathLOG, smoRestore.Database + "_Log.ldf");
  1058 + smorestoreLOGfile.LogicalFileName = dbfilelist.Select("Type='L'")[0]["LogicalName"].ToString();
  1059 + smoRestore.RelocateFiles.Add(smorestoreLOGfile);
  1060 +
  1061 + GetExclusiveUse(smoRestore.Database, sqlserver, sc);
  1062 + smoRestore.SqlRestore(sqlserver);
  1063 + ColorConsole.WriteLine();
  1064 + ColorConsole.WriteLine("Restore completed", ConsoleColor.Green);
  1065 + if (restorefromZIP && File.Exists(normalbackupfilepath)) { File.Delete(normalbackupfilepath); }
791 1066 }
  1067 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
792 1068 }
793 1069  
794 1070 /// <summary>
... ... @@ -798,34 +1074,27 @@ GO
798 1074 /// <param name="forcecreatezip"></param>
799 1075 /// <param name="timestamp"></param>
800 1076 /// <returns></returns>
801   - public static string CreateBackup(SQLDataBase sqld,bool? forcecreatezip, DateTime? timestamp)
  1077 + public static string CreateBackup(SQLDataBase sqld,bool? forcecreatezip, DateTime? timestamp,bool emulate=false)
802 1078 {
803 1079 string backupdirectorypath = sqld.Xml_BackupTargetDirectoryPath;
804   - string tranzitdirectorypathlocal = sqld.Xml_TranzitDirectoryPathLocal;
805   - string tranzitdirectorypathnetwork = sqld.Xml_TranzitDirectoryPathNetwork;
  1080 + string tranzitdirectorypath = sqld.Xml_TranzitDirectoryPath;
806 1081 bool usetranzit = sqld.Xml_IsRemoteDB;
807   - string sqlconnectionstring = sqld.SQLCS;
808 1082 string backupfilenamemask = sqld.Xml_BackupFileNameMask;
809 1083 bool createzip = forcecreatezip ?? sqld.Xml_CreateZip;
810 1084 //tranzitdirectorypathlocal = @"F:\ALM";
811 1085 //tranzitdirectorypathnetwork = @"\\matng-sql01\ALM";
812   - var sqlserver = SQLServerConnect(sqlconnectionstring);
813   - if (sqlserver == null)
814   - {
815   - ColorConsole.WriteLine($"ERROR! Database connection string error. '{sqlconnectionstring}'", ConsoleColor.Red);
816   - return null;
817   - }
818   -
  1086 +
819 1087 string returnfilename = null;
820   - var dbname = GetDBName(sqlconnectionstring);
  1088 + var dbname = GetDBName(sqld.SQLCS);
  1089 + var datasource = GetDataSource(sqld.SQLCS);
821 1090  
822 1091 var backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss");
823 1092  
824 1093 string backupfileNameOnly = Path.GetFileNameWithoutExtension(backupfilenamemask);
825 1094 var vars = new Dictionary<string, string>();
826   - vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlconnectionstring));
  1095 + vars.Add(nameof(DBSubstitutionName.DATABASE), dbname);
827 1096 vars.Add(nameof(DBSubstitutionName.DBKEY), sqld.Xml_Key);
828   - vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlconnectionstring));
  1097 + vars.Add(nameof(DBSubstitutionName.DATASOURCE), datasource);
829 1098 vars.Add(nameof(DBSubstitutionName.DBOTYPE), "DBBACKUP");
830 1099 vars.Add(nameof(DBSubstitutionName.DBONAME), "");
831 1100 vars.Add(nameof(DBSubstitutionName.DBDATAGROUP), "");
... ... @@ -835,70 +1104,90 @@ GO
835 1104  
836 1105 string backupfilename = backupfileNameOnly + ".bak";
837 1106 string backupFullName = Path.Combine(backupdirectorypath, backupfilename);
838   - string tranzitFullNameLocal= usetranzit ? Path.Combine(tranzitdirectorypathlocal, backupfilename) : null;
839   - string tranzitFullNameNetwork= usetranzit ? Path.Combine(tranzitdirectorypathnetwork, backupfilename) : null;
840   - if (File.Exists(backupFullName)) { File.Delete(backupFullName); }
841   -
842   -
843   - var smoBackup = new Backup();
844   - smoBackup.Action = BackupActionType.Database;
845   - smoBackup.BackupSetName = sqlserver.ConnectionContext.DatabaseName + " Backup";
846   - smoBackup.BackupSetDescription = $"Full Backup of {sqlserver.ConnectionContext.DatabaseName}";
847   - smoBackup.MediaDescription = "Disk";
  1107 + string tranzitFullName = usetranzit ? Path.Combine(tranzitdirectorypath, backupfilename) : null;
  1108 +
  1109 + string ZIPbackupfilename = backupfileNameOnly + ".zip";
  1110 + string ZIPbackupFullName = Path.Combine(backupdirectorypath, ZIPbackupfilename);
  1111 + returnfilename = createzip? ZIPbackupFullName : backupFullName;
  1112 +
  1113 + ColorConsole.WriteLine(nameof(CreateBackup), ConsoleColor.Yellow, prefix: "running....");
  1114 + ColorConsole.WriteLine(dbname, ConsoleColor.Yellow, prefix: " dbname:");
  1115 + ColorConsole.WriteLine(sqld.SQLCS, ConsoleColor.Yellow, prefix: " sqld.SQLCS:");
  1116 + ColorConsole.WriteLine(backupdirectorypath, ConsoleColor.Yellow, prefix: " backupdirectorypath:");
  1117 + ColorConsole.WriteLine(backupfilename, ConsoleColor.Yellow, prefix: " backupfilename:");
  1118 + ColorConsole.WriteLine(backupFullName, ConsoleColor.Yellow, prefix: " backupFullName:");
  1119 + ColorConsole.WriteLine(createzip.ToString(), ConsoleColor.Yellow, prefix: " createzip:");
  1120 + ColorConsole.WriteLine(ZIPbackupfilename, ConsoleColor.Yellow, prefix: " ZIPbackupfilename:");
  1121 + ColorConsole.WriteLine(ZIPbackupFullName, ConsoleColor.Yellow, prefix: " ZIPbackupFullName:");
  1122 + ColorConsole.WriteLine(usetranzit.ToString(), ConsoleColor.Yellow, prefix: " usetranzit:");
  1123 + ColorConsole.WriteLine(tranzitFullName, ConsoleColor.Yellow, prefix: " tranzitFullName:");
  1124 + ColorConsole.WriteLine(returnfilename, ConsoleColor.Yellow, prefix: " returnfilename:");
  1125 +
  1126 + if (!emulate)
  1127 + {
  1128 + ColorConsole.WriteLine($"Database backup started...", ConsoleColor.DarkGreen);
  1129 + if (File.Exists(backupFullName)) { File.Delete(backupFullName); }
  1130 + var smoBackup = new Backup();
  1131 + smoBackup.Database = dbname;
  1132 + smoBackup.Action = BackupActionType.Database;
  1133 + smoBackup.BackupSetName = smoBackup.Database + " Backup";
  1134 + smoBackup.BackupSetDescription = $"Full Backup of {smoBackup.Database}";
  1135 + smoBackup.MediaDescription = "Disk";
848 1136 Console.WriteLine($"Backup set: {smoBackup.BackupSetName} ({smoBackup.BackupSetDescription}) to media: {smoBackup.MediaDescription}");
849   - smoBackup.Database = sqlserver.ConnectionContext.DatabaseName;
850 1137 string dummystring = usetranzit ? " REMOTE SQL SERVER!" : "";
851 1138 Console.WriteLine($"Database name: {smoBackup.Database}{dummystring}");
852 1139 Console.WriteLine($"Connection string: {sqld.SQLCS}");
853   - smoBackup.Devices.AddDevice(usetranzit ? tranzitFullNameLocal : backupFullName, DeviceType.File);
  1140 + smoBackup.Devices.AddDevice(usetranzit ? tranzitFullName : backupFullName, DeviceType.File);
854 1141 Console.WriteLine($"Backup full name:{backupFullName}");
855   - if (usetranzit)
  1142 + if (usetranzit)
856 1143 {
857   - Console.WriteLine($" ...will be created through tranzit: {tranzitFullNameNetwork}");
  1144 + Console.WriteLine($" ...will be created through tranzit: {tranzitFullName}");
  1145 + }
  1146 + smoBackup.PercentComplete += SmoBackupRestore_PercentComplete;
  1147 + smoBackup.PercentCompleteNotification = 1;
  1148 +
  1149 + Server sqlserver = null;
  1150 + try
  1151 + {
  1152 + sqlserver = SQLServerConnect(sqld.SQLCS, "master"); if (sqlserver == null) { return null; }
  1153 + smoBackup.SqlBackupAsync(sqlserver);
  1154 + var startbackup = DateTime.Now;
  1155 + smoBackup.Wait();
  1156 + Console.WriteLine($"");
  1157 + Console.WriteLine($"Backup completed. Backup time: {(int)(DateTime.Now.Subtract(startbackup).TotalSeconds)}sec.");
  1158 + }
  1159 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
  1160 + if (usetranzit && File.Exists(tranzitFullName))
  1161 + {
  1162 + File.Move(tranzitFullName, backupFullName);
  1163 + Console.WriteLine($"Moving backup file...");
  1164 + Console.WriteLine($" ...from tranzit location: {tranzitFullName}");
  1165 + Console.WriteLine($" ...to backup location: {backupFullName}");
  1166 + }
  1167 + if (!File.Exists(backupFullName))
  1168 + {
  1169 + ColorConsole.WriteLine($"ERROR! Database backup failed. DB name:'{smoBackup.Database}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.Red);
  1170 + return null;
858 1171 }
859   - smoBackup.PercentComplete += SmoBackup_PercentComplete;
860   - smoBackup.PercentCompleteNotification = 1;
861   - smoBackup.SqlBackupAsync(sqlserver);
862   - var startbackup = DateTime.Now;
863   - smoBackup.Wait();
864   - Console.WriteLine($"");
865   - Console.WriteLine($"Backup completed. Backup time: {(int)(DateTime.Now.Subtract(startbackup).TotalSeconds)}sec.");
866   - if (usetranzit && File.Exists(tranzitFullNameNetwork))
867   - {
868   - File.Move(tranzitFullNameNetwork, backupFullName);
869   - Console.WriteLine($"Moving backup file...");
870   - Console.WriteLine($" ...from tranzit location: {tranzitFullNameNetwork}");
871   - Console.WriteLine($" ...to backup location: {backupFullName}");
872   - }
873   - returnfilename = backupFullName;
874   - if (File.Exists(backupFullName))
875   - {
876 1172 if (createzip)
877 1173 {
878 1174 var startcompressing = DateTime.Now;
879   - string ZIPbackupfilename = backupfileNameOnly + ".zip";
880   - string ZIPbackupFullName = Path.Combine(backupdirectorypath, ZIPbackupfilename);
881 1175 if (File.Exists(ZIPbackupFullName)) { File.Delete(ZIPbackupFullName); }
882 1176  
883 1177 ZipTools.CreateEntriesFromDirectoryContent(backupdirectorypath, ZIPbackupFullName, backupfilename, "", "", removearchivedfiles: false, storepathinzip: false);
884 1178 File.Delete(backupFullName);
885 1179 Console.WriteLine($"Zipping completed. Compressing time: {(int)(DateTime.Now.Subtract(startcompressing).TotalSeconds)}sec.");
886   - returnfilename = ZIPbackupFullName;
887 1180 }
888   - ColorConsole.WriteLine($"SUCCESS! Database backup created. DB name:'{dbname}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.DarkGreen);
889   - }
890   - else
891   - {
892   - ColorConsole.WriteLine($"ERROR! Database backup failed. DB name:'{dbname}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.Red);
  1181 + ColorConsole.WriteLine($"SUCCESS! Database backup created. DB name:'{smoBackup.Database}'. BAK/ZIP file name:'{Path.GetFileName(returnfilename)}'", ConsoleColor.DarkGreen);
893 1182 }
894 1183 return returnfilename;
895 1184 }
896 1185  
897   - private static void SmoBackup_PercentComplete(object sender, PercentCompleteEventArgs e)
  1186 + private static void SmoBackupRestore_PercentComplete(object sender, PercentCompleteEventArgs e)
898 1187 {
899   - Console.SetCursorPosition(0, Console.CursorTop);
900   - Console.Write($"Database backup completed: {e.Percent}%. {e.Message}");
901   - }
  1188 + ColorConsole.SetCursorPosition(0, Console.CursorTop);
  1189 + ColorConsole.Write($"Completed: {e.Percent}%. {e.Message}");
  1190 + }
902 1191  
903 1192 #region private methods
904 1193 public static List<FileInfo> GetBackupFilePathList(SQLDataBase sqld)
... ... @@ -926,16 +1215,21 @@ GO
926 1215 /// <returns></returns>
927 1216 public static string ConfigureSaUser(string cs,string password, string newsapassword)
928 1217 {
929   - var sqlserver = SQLServerConnect(cs);
930   - sqlserver.Settings.LoginMode= ServerLoginMode.Mixed;
931   - sqlserver.Logins["sa"].Enable();
932   - sqlserver.Logins.ItemById(10).Enable();
933   - sqlserver.Logins["sa"].ChangePassword(newsapassword);
934   - sqlserver.Alter();
935   - sqlserver.Logins["a"].Refresh();
936   - return SQLServerConnect(cs).ConnectionContext.ConnectionString;
  1218 + Server sqlserver = null;
  1219 + try
  1220 + {
  1221 + sqlserver = SQLServerConnect(cs); if (sqlserver == null) return null;
  1222 + sqlserver.Settings.LoginMode = ServerLoginMode.Mixed;
  1223 + sqlserver.Logins["sa"].Enable();
  1224 + sqlserver.Logins.ItemById(10).Enable();
  1225 + sqlserver.Logins["sa"].ChangePassword(newsapassword);
  1226 + sqlserver.Alter();
  1227 + sqlserver.Logins["a"].Refresh();
  1228 + return sqlserver.ConnectionContext.ConnectionString;
  1229 + }
  1230 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
937 1231 }
938   - public static void CreateUser(string sqldbconnectionString, string dbusername, string dbrolenamecommalist)
  1232 + public static void CreateUser(string sqldbconnectionString, string dbusername, string dbrolenamecommalist,string loginname)
939 1233 {
940 1234 using (SqlConnection connection = new SqlConnection(sqldbconnectionString))
941 1235 {
... ... @@ -944,7 +1238,37 @@ GO
944 1238 //USE [LearALM2]
945 1239 //DROP USER[datareader]
946 1240  
947   - string createUserQuery = "CREATE USER [" + dbusername + "] FOR LOGIN [" + dbusername + "];";
  1241 + //empty=DB user w/o login, *=DB user with login,w=WIndows user, other=server login name DB user is created for
  1242 + bool? forlogin;
  1243 + if (string.IsNullOrWhiteSpace(loginname)) { forlogin = false; loginname = null; }
  1244 + else if (loginname.ToLower() == "w") { forlogin = null; loginname = null; }
  1245 + else { forlogin = true; loginname = loginname == "*"?dbusername: loginname; }
  1246 +
  1247 + //Creating a database user based on a SQL Server login
  1248 + // CREATE LOGIN AbolrousHazem WITH PASSWORD = '340$Uuxwp7Mcxo7Khy';
  1249 + // GO
  1250 + // USE AdventureWorks2022
  1251 + // GO
  1252 + // CREATE USER AbolrousHazem FOR LOGIN AbolrousHazem;
  1253 + // GO
  1254 + //Creating and using a user without a login
  1255 + // USE AdventureWorks2022;
  1256 + // CREATE USER CustomApp WITHOUT LOGIN;
  1257 + // GRANT IMPERSONATE ON USER::CustomApp TO[adventure - works\tengiz0];
  1258 + // GO
  1259 + // To use the CustomApp credentials, the user adventure-works\tengiz0 executes the following statement.
  1260 + // EXECUTE AS USER = 'CustomApp' ;
  1261 + //Creating a contained database user for a domain login for a login named Fritz in a domain named Contoso.
  1262 + // USE AdventureWorks2022;
  1263 + // GO
  1264 + // CREATE USER [Contoso\Fritz];
  1265 + // GO
  1266 +
  1267 + string createUserQuery = "CREATE USER [" + dbusername + "]";
  1268 + if (forlogin.HasValue && forlogin.Value) {createUserQuery += " FOR LOGIN [" + loginname + "];"; }
  1269 + else if (forlogin.HasValue && !forlogin.Value) { createUserQuery = " WITHOUT LOGIN;"; }
  1270 + createUserQuery += ";";
  1271 +
948 1272 using (SqlCommand createUserCommand = new SqlCommand(createUserQuery, connection)) { createUserCommand.ExecuteNonQuery(); }
949 1273 //--ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_BasicAccess] TO[dbo]
950 1274 //--ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_FullAccess] TO[dbo]
... ... @@ -955,113 +1279,198 @@ GO
955 1279 string grantPermissionsQuery = "EXEC sp_addrolemember N'"+ rolename + "', N'"+ dbusername + "'";
956 1280 using (SqlCommand grantPermissionsCommand = new SqlCommand(grantPermissionsQuery, connection)) { grantPermissionsCommand.ExecuteNonQuery(); }
957 1281 }
958   - }
959   - }
960   - public static void CreateLogin(string sqldbconnectionString, string name, string password, string defaultDatabase, string[] roles)
961   - {
962   - var _server = SQLServerConnect(sqldbconnectionString);
963   - Login login = new Login(_server, name);
964   - login.LoginType = LoginType.SqlLogin;
965   - login.DefaultDatabase = defaultDatabase;
966   -
967   - login.PasswordExpirationEnabled = false;
968   - login.PasswordPolicyEnforced = false;
969 1282  
970   - login.Create(password, LoginCreateOptions.None);
971 1283  
972   - for (int i = 0; i < (roles==null?-1:roles.Length); i++) { login.AddToRole(roles[i]); }
  1284 + //USE[LearALM2]
  1285 + //ALTER AUTHORIZATION ON SCHEMA::[ALM] TO[dbo]
  1286 + //ALTER AUTHORIZATION ON SCHEMA::[Andon] TO[dbo]
  1287 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_BasicAccess] TO[dbo]
  1288 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_FullAccess] TO[dbo]
  1289 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Membership_ReportingAccess] TO[dbo]
  1290 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Personalization_BasicAccess] TO[dbo]
  1291 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Personalization_FullAccess] TO[dbo]
  1292 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Personalization_ReportingAccess] TO[dbo]
  1293 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Profile_BasicAccess] TO[dbo]
  1294 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Profile_FullAccess] TO[dbo]
  1295 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Profile_ReportingAccess] TO[dbo]
  1296 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Roles_BasicAccess] TO[dbo]
  1297 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Roles_FullAccess] TO[dbo]
  1298 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_Roles_ReportingAccess] TO[dbo]
  1299 + //ALTER AUTHORIZATION ON SCHEMA::[aspnet_WebEvent_FullAccess] TO[dbo]
  1300 + //ALTER AUTHORIZATION ON SCHEMA::[CP] TO[dbo]
  1301 + //ALTER AUTHORIZATION ON SCHEMA::[db_accessadmin] TO[dbo]
  1302 + //ALTER AUTHORIZATION ON SCHEMA::[db_backupoperator] TO[dbo]
  1303 + //ALTER AUTHORIZATION ON SCHEMA::[db_datareader] TO[dbo]
  1304 + //ALTER AUTHORIZATION ON SCHEMA::[db_datawriter] TO[dbo]
  1305 + //ALTER AUTHORIZATION ON SCHEMA::[db_ddladmin] TO[dbo]
  1306 + //ALTER AUTHORIZATION ON SCHEMA::[db_denydatareader] TO[dbo]
  1307 + //ALTER AUTHORIZATION ON SCHEMA::[db_denydatawriter] TO[dbo]
  1308 + //ALTER AUTHORIZATION ON SCHEMA::[db_owner] TO[dbo]
  1309 + //ALTER AUTHORIZATION ON SCHEMA::[db_securityadmin] TO[dbo]
  1310 + //ALTER AUTHORIZATION ON SCHEMA::[guest] TO[dbo]
  1311 + //ALTER AUTHORIZATION ON SCHEMA::[i18n] TO[dbo]
  1312 + //ALTER AUTHORIZATION ON SCHEMA::[IdTranslator] TO[dbo]
  1313 + //ALTER AUTHORIZATION ON SCHEMA::[ImportLog] TO[dbo]
  1314 + //ALTER AUTHORIZATION ON SCHEMA::[iScheduler] TO[dbo]
  1315 + //ALTER AUTHORIZATION ON SCHEMA::[iSchedulerReports] TO[dbo]
973 1316  
974   - login.Alter();
975   - login.Enable();
976   - login.Alter();
  1317 + }
  1318 + }
  1319 + public static void CreateLogin(string sqldbconnectionString, string name, string password, string defaultDatabase, LoginType logintype, string[] roles,string grantoruser=null,string grantoruserpsw=null)
  1320 + {
  1321 + Server sqlserver = null;
  1322 + try
  1323 + {
  1324 + var sc = GetSqlConnection(sqldbconnectionString,null, grantoruser, grantoruserpsw);
  1325 + sqlserver = SQLServerConnect(sc); if (sqlserver == null) return;
  1326 + Login login = new Login(sqlserver, name);
  1327 + login.LoginType = logintype;
  1328 + login.DefaultDatabase = defaultDatabase;
  1329 +
  1330 + login.PasswordExpirationEnabled = false;
  1331 + login.PasswordPolicyEnforced = false;
  1332 + if (password == null) { login.Create(); }
  1333 + else { login.Create(password, LoginCreateOptions.None); }
  1334 +
  1335 + for (int i = 0; i < (roles == null ? -1 : roles.Length); i++) { login.AddToRole(roles[i]); }
  1336 +
  1337 + login.Alter();
  1338 + login.Enable();
  1339 + login.Alter();
  1340 + }
  1341 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
977 1342 }
978 1343  
979 1344 public static void ConfigureWindowsUser(string cs, string sapassword, string databasename, string windowsfullusername,string windowsuserpassword,List<string> rolenamelist)
980 1345 {
981   - var sqlserver = SQLServerConnect(cs);
982   - if (!sqlserver.Logins.Contains(windowsfullusername))
  1346 + Server sqlserver = null;
  1347 + try
983 1348 {
984   - var wul = new Microsoft.SqlServer.Management.Smo.Login(sqlserver, windowsfullusername);
985   - wul.LoginType = LoginType.WindowsUser;
986   - wul.Create(windowsuserpassword,LoginCreateOptions.None);
987   - if (!string.IsNullOrWhiteSpace(databasename))
  1349 + sqlserver = SQLServerConnect(cs); if (sqlserver == null) return;
  1350 + if (!sqlserver.Logins.Contains(windowsfullusername))
988 1351 {
989   - var dbobject = sqlserver.Databases[databasename];
990   - if (dbobject==null) { throw new Exception($"Specified databas '{databasename}' does not exist!"); }
991   - if (dbobject.Users.Contains(windowsfullusername)) { dbobject.Users[windowsfullusername].Drop(); }
992   - var dbuser = new Microsoft.SqlServer.Management.Smo.User(dbobject, windowsfullusername);
993   - dbuser.Login = windowsfullusername;
994   - dbuser.Create(windowsuserpassword);
995   - foreach (var rn in rolenamelist)
996   - {
997   - var dbrole = dbobject.Roles[rn];
998   - dbrole.AddMember(windowsfullusername);
999   - dbrole.Alter();
  1352 + var wul = new Microsoft.SqlServer.Management.Smo.Login(sqlserver, windowsfullusername);
  1353 + wul.LoginType = LoginType.WindowsUser;
  1354 + wul.Create(windowsuserpassword, LoginCreateOptions.None);
  1355 + if (!string.IsNullOrWhiteSpace(databasename))
  1356 + {
  1357 + var dbobject = sqlserver.Databases[databasename];
  1358 + if (dbobject == null) { throw new Exception($"Specified databas '{databasename}' does not exist!"); }
  1359 + if (dbobject.Users.Contains(windowsfullusername)) { dbobject.Users[windowsfullusername].Drop(); }
  1360 + var dbuser = new Microsoft.SqlServer.Management.Smo.User(dbobject, windowsfullusername);
  1361 + dbuser.Login = windowsfullusername;
  1362 + dbuser.Create(windowsuserpassword);
  1363 + foreach (var rn in rolenamelist)
  1364 + {
  1365 + var dbrole = dbobject.Roles[rn];
  1366 + dbrole.AddMember(windowsfullusername);
  1367 + dbrole.Alter();
  1368 + }
1000 1369 }
1001 1370 }
1002 1371 }
  1372 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
1003 1373 }
1004   - public static void DropDatabase(string cs,string databasename,string sapassword)
  1374 + public static bool DropDatabase(string cs,string databasename,string userid, string password)
1005 1375 {
1006   - var sqlserver = SQLServerConnect(cs);
1007   - if (sqlserver.Databases.Contains(databasename))
  1376 + Server sqlserver = null;
  1377 + try
1008 1378 {
1009   - sqlserver.KillAllProcesses(databasename);
1010   - sqlserver.Databases[databasename].Drop();
  1379 + var sc = GetSqlConnection(cs, dbname:databasename, userid: userid, userpassword: password);
  1380 + sqlserver = SQLServerConnect(sc); if (sqlserver == null) return false;
  1381 + if (sqlserver.Databases.Contains(databasename))
  1382 + {
  1383 + GetExclusiveUse(databasename, sqlserver, sc);
  1384 + sqlserver.Databases[databasename].Drop();
  1385 + return true;
  1386 + }
  1387 + else { throw new ApplicationException($"Specified DB '{databasename}' does not exist!"); }
1011 1388 }
1012   - else { throw new Exception($"Specified databas '{databasename}' does not exist!"); }
  1389 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); return false; }
  1390 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
  1391 + }
  1392 + public static void GetExclusiveUse(string databasename,Server sqlserver,SqlConnection sc)
  1393 + {
  1394 + try { sqlserver.KillAllProcesses(databasename); }
  1395 + catch (Exception ex) { ColorConsole.WriteLine($"{nameof(GetExclusiveUse)}/{nameof(Server.KillAllProcesses)}>>>:" + ex.MessageNested(), ConsoleColor.Red); }
  1396 +
  1397 + SqlCommand sqlcommand = null;
  1398 + try { sqlcommand = new SqlCommand($"ALTER DATABASE {databasename} SET Single_User WITH Rollback IMMEDIATE", sc); sqlcommand.ExecuteNonQuery(); }
  1399 + catch (Exception ex) { ColorConsole.WriteLine($"{nameof(GetExclusiveUse)}/{nameof(SqlCommand.ExecuteNonQuery)}>>>: " + ex.MessageNested(), ConsoleColor.Red); }
  1400 + finally { sqlcommand?.Dispose(); }
1013 1401 }
  1402 +
1014 1403 public static string GetServerDefaultPhysicalDATFileLocation(string cs)
1015 1404 {
1016   - var sqlserver = SQLDataBaseManagerCore.SQLServerConnect(cs);
1017   - return string.IsNullOrEmpty(sqlserver.DefaultFile) ? sqlserver.MasterDBPath : sqlserver.DefaultFile;
  1405 + Server sqlserver = null;
  1406 + try
  1407 + {
  1408 + sqlserver = SQLServerConnect(cs); if (sqlserver == null) return null;
  1409 + return string.IsNullOrEmpty(sqlserver.DefaultFile) ? sqlserver.MasterDBPath : sqlserver.DefaultFile;
  1410 + }
  1411 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
1018 1412 }
1019 1413 public static string GetServerDefaultPhysicalLOGFileLocation(string cs)
1020 1414 {
1021   - var sqlserver = SQLDataBaseManagerCore.SQLServerConnect(cs);
1022   - return string.IsNullOrEmpty(sqlserver.DefaultLog) ? sqlserver.MasterDBLogPath : sqlserver.DefaultLog;
  1415 + Server sqlserver = null;
  1416 + try
  1417 + {
  1418 + sqlserver = SQLServerConnect(cs);if (sqlserver == null) return null;
  1419 + return string.IsNullOrEmpty(sqlserver.DefaultLog) ? sqlserver.MasterDBLogPath : sqlserver.DefaultLog;
  1420 + }
  1421 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
1023 1422 }
1024 1423 public static string GetDBName(string cs)
1025 1424 {
1026   - var sqlc = new Microsoft.Data.SqlClient.SqlConnection(cs);
1027   - return sqlc.Database;
  1425 + var sqlcb = new SqlConnectionStringBuilder(cs);
  1426 + return sqlcb.InitialCatalog;
1028 1427 }
1029 1428 public static string GetDataSource(string cs)
1030 1429 {
1031   - var sqlc = new Microsoft.Data.SqlClient.SqlConnection(cs);
1032   - return sqlc.DataSource;
  1430 + var sqlcb = new SqlConnectionStringBuilder(cs);
  1431 + return sqlcb.DataSource;
1033 1432 }
1034 1433 public enum SQLDBStatus { NoAccess, OK, }
1035   - public static SQLDBStatus GetStatus(string cs)
  1434 + public static SqlConnection GetSqlConnection(string sqlconnectionstring, string dbname = null, string userid = null, string userpassword = null)
1036 1435 {
1037   - try
1038   - {
1039   - var s = GetPhysicalFilesLocation(cs);
1040   - if (s == null) { throw new Exception(); };
1041   - return SQLDBStatus.OK;
1042   - }
1043   - catch { return SQLDBStatus.NoAccess; }
  1436 + var scb = new SqlConnectionStringBuilder(sqlconnectionstring);
  1437 + if (!string.IsNullOrWhiteSpace(dbname)) { scb.InitialCatalog = dbname; }
  1438 + if (!string.IsNullOrWhiteSpace(userid) && !string.IsNullOrWhiteSpace(userpassword)) { scb.UserID = userid; scb.Password = userpassword; }
  1439 + else if (!string.IsNullOrWhiteSpace(userid) && string.IsNullOrWhiteSpace(userpassword)) { scb.UserID= userid; scb.IntegratedSecurity= true; }
  1440 + return new SqlConnection(scb.ToString());
1044 1441 }
1045   - public static Server SQLServerConnect(string sqlconnectionstring)
  1442 + public static Server SQLServerConnect(string sqlconnectionstring,string dbname=null)
1046 1443 {
  1444 + return SQLServerConnect(GetSqlConnection(sqlconnectionstring, dbname));
  1445 + }
  1446 + public static Server SQLServerConnect(SqlConnection sqlconnection)
  1447 + {
  1448 + if (sqlconnection == null) return null;
1047 1449 try
1048 1450 {
1049   - var sqlconnection = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring);
  1451 + ColorConsole.WriteLine($"{nameof(SQLServerConnect)}. Connecting to: '{sqlconnection.ConnectionString}'", ConsoleColor.Yellow);
1050 1452 var serverconnection = new ServerConnection(sqlconnection);
1051 1453 var sqlserver = new Server(serverconnection);
1052   - if (string.IsNullOrEmpty(sqlserver.Information.Version.ToString())) { throw new Exception("Connection not established!"); }
  1454 + ColorConsole.WriteLine($"{nameof(SQLServerConnect)}. Connected. Server version:v{sqlserver.Information.Version}", ConsoleColor.Yellow);
1053 1455 return sqlserver;
1054 1456 }
1055   - catch (Exception ex) { throw ex; }
  1457 + catch (Exception ex)
  1458 + {
  1459 + ColorConsole.WriteLine($"{nameof(SQLServerConnect)}. ERROR! Connecting to: '{sqlconnection.ConnectionString}'", ConsoleColor.Red);
  1460 + ColorConsole.WriteLine(ex.MessageNested());
  1461 + throw ex;
  1462 + }
1056 1463 }
1057 1464  
1058 1465 public static void ShrinkDB(string sqlconnectionstring, ShrinkMethod shrinkmethod,int freespacepercent)
1059 1466 {
1060   - var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring);
1061   - var sc = new ServerConnection(sqlc);
1062   - var srvr = new Server(sc);
1063   - var db = new Database(srvr, GetDBName(sqlconnectionstring));
1064   - db.Shrink(freespacepercent, shrinkmethod);
  1467 + using (var sqlc = new SqlConnection(sqlconnectionstring))
  1468 + {
  1469 + var sc = new ServerConnection(sqlc);
  1470 + var srvr = new Server(sc);
  1471 + var db = new Database(srvr, GetDBName(sqlconnectionstring));
  1472 + db.Shrink(freespacepercent, shrinkmethod);
  1473 + }
1065 1474 }
1066 1475  
1067 1476 #region GetSize
... ... @@ -1074,25 +1483,26 @@ GO
1074 1483 {
1075 1484 try
1076 1485 {
1077   - var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring);
1078   - var dbname = GetDBName(sqlconnectionstring);
  1486 + using (var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring))
  1487 + {
  1488 + var dbname = GetDBName(sqlconnectionstring);
1079 1489  
1080   - var getsizecmd = new Microsoft.Data.SqlClient.SqlCommand("sp_spaceused", sqlc);
1081   - getsizecmd.CommandType = System.Data.CommandType.StoredProcedure;
1082   - sqlc.Open();
1083   - var reader = getsizecmd.ExecuteReader();
  1490 + var getsizecmd = new Microsoft.Data.SqlClient.SqlCommand("sp_spaceused", sqlc);
  1491 + getsizecmd.CommandType = System.Data.CommandType.StoredProcedure;
  1492 + sqlc.Open();
  1493 + var reader = getsizecmd.ExecuteReader();
1084 1494  
1085   - if (reader.HasRows)
1086   - {
1087   - while (reader.Read())
  1495 + if (reader.HasRows)
1088 1496 {
1089   - var dbn = reader["database_name"];
1090   - var dbs = reader["database_size"];
1091   - if (Convert.ToString(dbn) == dbname) { return Convert.ToString(dbs); };
  1497 + while (reader.Read())
  1498 + {
  1499 + var dbn = reader["database_name"];
  1500 + var dbs = reader["database_size"];
  1501 + if (Convert.ToString(dbn) == dbname) { return Convert.ToString(dbs); };
  1502 + }
1092 1503 }
  1504 + sqlc.Close();
1093 1505 }
1094   - sqlc.Close();
1095   - sqlc.Dispose();
1096 1506 return "N/A";
1097 1507 }
1098 1508 catch { return "ERR"; }
... ... @@ -1152,46 +1562,47 @@ GO
1152 1562 /// </returns>
1153 1563 public static ReturnInfoJSON ExecuteSQLScript(string sqlconnectionstring, string sqltxt, int commandtimeout, Dictionary<string, string> vars)
1154 1564 {
1155   - var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring);
1156   -
1157   - sqltxt = VRH.Common.StringConstructor.ResolveConstructorR(vars, sqltxt, "{}@@");
1158   -
1159   - sqlc.Open();
1160   - string SQLBatchTxt = ""; // ebben lesznek az sql script-en belüli batch-ek összerakva
1161   - int SQLBatchIndex = 0; // az aktuális batch indexe
1162   - int scriptlineindex = 0; // az aktuális script sor indexe
1163   - System.Data.DataSet DataSet = null; // ebben lesz az eredmény (az utolsó batch eredménye)
1164   - sqltxt += "\r\nGO";// ha esetleg nem lenne, odatesszük a végére az utolsó batch-et lezáró GO-t
1165   - foreach (var scriptline in sqltxt.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
  1565 + using (var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring))
1166 1566 {
1167   - scriptlineindex += 1;
1168   - if (Regex.Match(scriptline, @"^GO$").Success)// a batch utolső sora
  1567 + sqltxt = VRH.Common.StringConstructor.ResolveConstructorR(vars, sqltxt, "{}@@");
  1568 +
  1569 + sqlc.Open();
  1570 + string SQLBatchTxt = ""; // ebben lesznek az sql script-en belüli batch-ek összerakva
  1571 + int SQLBatchIndex = 0; // az aktuális batch indexe
  1572 + int scriptlineindex = 0; // az aktuális script sor indexe
  1573 + System.Data.DataSet DataSet = null; // ebben lesz az eredmény (az utolsó batch eredménye)
  1574 + sqltxt += "\r\nGO";// ha esetleg nem lenne, odatesszük a végére az utolsó batch-et lezáró GO-t
  1575 + foreach (var scriptline in sqltxt.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
1169 1576 {
1170   - if (!string.IsNullOrWhiteSpace(SQLBatchTxt))
  1577 + scriptlineindex += 1;
  1578 + if (Regex.Match(scriptline, @"^GO$").Success)// a batch utolső sora
1171 1579 {
1172   - SQLBatchIndex += 1;
1173   - DataSet = ExecuteSQLScriptBatch(sqlc, SQLBatchTxt, commandtimeout);
1174   - SQLBatchTxt = "";
  1580 + if (!string.IsNullOrWhiteSpace(SQLBatchTxt))
  1581 + {
  1582 + SQLBatchIndex += 1;
  1583 + DataSet = ExecuteSQLScriptBatch(sqlc, SQLBatchTxt, commandtimeout);
  1584 + SQLBatchTxt = "";
  1585 + }
  1586 + }
  1587 + else if (!string.IsNullOrWhiteSpace(scriptline))
  1588 + {
  1589 + SQLBatchTxt += scriptline + "\r\n";
1175 1590 }
1176 1591 }
1177   - else if (!string.IsNullOrWhiteSpace(scriptline))
  1592 +
  1593 + sqlc.Close();
  1594 + try
1178 1595 {
1179   - SQLBatchTxt += scriptline + "\r\n";
  1596 + var firstreturnedtable = DataSet.Tables[0];
  1597 + var firstreturnedrow = firstreturnedtable.Rows[0];
  1598 + var firstreturnedvalue = firstreturnedrow[0];
  1599 + var secondreturnedvalue = firstreturnedrow[1];
  1600 + var rv = Convert.ToInt32(firstreturnedvalue);
  1601 + var rm = Convert.ToString(secondreturnedvalue);
  1602 + return new ReturnInfoJSON() { ReturnValue = rv, ReturnMessage = rm, };
1180 1603 }
  1604 + catch { }
1181 1605 }
1182   -
1183   - sqlc.Close();
1184   - try
1185   - {
1186   - var firstreturnedtable = DataSet.Tables[0];
1187   - var firstreturnedrow = firstreturnedtable.Rows[0];
1188   - var firstreturnedvalue = firstreturnedrow[0];
1189   - var secondreturnedvalue = firstreturnedrow[1];
1190   - var rv = Convert.ToInt32(firstreturnedvalue);
1191   - var rm = Convert.ToString(secondreturnedvalue);
1192   - return new ReturnInfoJSON() { ReturnValue = rv, ReturnMessage = rm, };
1193   - }
1194   - catch { }
1195 1606 return new ReturnInfoJSON() { ReturnValue = 0, ReturnMessage = null, };
1196 1607 }
1197 1608  
... ... @@ -1252,38 +1663,40 @@ GO
1252 1663  
1253 1664 public static List<SPparameter> ExecuteSQLStoredProcedure(string sqlconnectionstring, string storedprocedurename, int commandtimeout, List<SPparameter> SPparameters)
1254 1665 {
1255   - var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring);
1256   - var sqlcommand = sqlc.CreateCommand();
1257   - sqlcommand.Connection = sqlc;
1258   - sqlcommand.CommandText = storedprocedurename;
1259   - sqlcommand.CommandTimeout = commandtimeout;
1260   - sqlcommand.CommandType= System.Data.CommandType.StoredProcedure;
1261   - //var DataAdapter = new Microsoft.Data.SqlClient.SqlDataAdapter(sqlcommand);
1262   - sqlc.Open();
1263   - foreach (var p in SPparameters)
1264   - {
1265   - var sqlparameter = new Microsoft.Data.SqlClient.SqlParameter()
1266   - {
1267   - ParameterName = p.Name,
1268   - SqlDbType = p.Type,
1269   - Size = p.Typepar,
1270   - Direction = p.Direction,
1271   - Value = p.Value,
1272   - };
1273   - sqlcommand.Parameters.Add(sqlparameter);
1274   - }
1275   - sqlcommand.ExecuteNonQuery();
  1666 + using (var sqlc = new Microsoft.Data.SqlClient.SqlConnection(sqlconnectionstring))
  1667 + {
  1668 + var sqlcommand = sqlc.CreateCommand();
  1669 + sqlcommand.Connection = sqlc;
  1670 + sqlcommand.CommandText = storedprocedurename;
  1671 + sqlcommand.CommandTimeout = commandtimeout;
  1672 + sqlcommand.CommandType = System.Data.CommandType.StoredProcedure;
  1673 + //var DataAdapter = new Microsoft.Data.SqlClient.SqlDataAdapter(sqlcommand);
  1674 + sqlc.Open();
  1675 + foreach (var p in SPparameters)
  1676 + {
  1677 + var sqlparameter = new Microsoft.Data.SqlClient.SqlParameter()
  1678 + {
  1679 + ParameterName = p.Name,
  1680 + SqlDbType = p.Type,
  1681 + Size = p.Typepar,
  1682 + Direction = p.Direction,
  1683 + Value = p.Value,
  1684 + };
  1685 + sqlcommand.Parameters.Add(sqlparameter);
  1686 + }
  1687 + sqlcommand.ExecuteNonQuery();
1276 1688  
1277   - var sqlresult = new List<SPparameter>();
1278   - foreach (var p in SPparameters)
1279   - {
1280   - if (p.Direction == System.Data.ParameterDirection.Output)
  1689 + var sqlresult = new List<SPparameter>();
  1690 + foreach (var p in SPparameters)
1281 1691 {
1282   - sqlresult.Add(new SPparameter(sqlcommand.Parameters[p.Name]));
  1692 + if (p.Direction == System.Data.ParameterDirection.Output)
  1693 + {
  1694 + sqlresult.Add(new SPparameter(sqlcommand.Parameters[p.Name]));
  1695 + }
1283 1696 }
  1697 + sqlc.Close();
  1698 + return sqlresult;
1284 1699 }
1285   - sqlc.Close();
1286   - return sqlresult;
1287 1700 }
1288 1701 #endregion ExecuteSQLStoredProcedure
1289 1702 #region BackupSqlScripts
... ... @@ -1298,35 +1711,38 @@ GO
1298 1711 string backupfilenamemask = sqld.Xml_BackupFileNameMask;
1299 1712 string sqlcs = sqld.SQLCS;
1300 1713 bool createZip = sqld.Xml_CreateZip;
1301   - var sqlserver = SQLServerConnect(sqlcs);
  1714 +
1302 1715 var dbname = GetDBName(sqlcs);
1303   - if (sqlserver!=null)
  1716 + string backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss");
  1717 + var vars = new Dictionary<string, string>();
  1718 + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlcs));
  1719 + vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlcs));
  1720 + vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts);
  1721 + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "Scripts");
  1722 +
  1723 + string zipfilefullpath = null;
  1724 + string tempbackupdirectorypath;
  1725 + if (createZip)
1304 1726 {
1305   - string backupts = (timestamp.HasValue? timestamp.Value:DateTime.Now).ToString("yyyyMMddHHmmss");
1306   - var vars = new Dictionary<string, string>();
1307   - vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlcs));
1308   - vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlcs));
1309   - vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts);
1310   - vars.Add(nameof(DBSubstitutionName.DBOTYPE), "Scripts");
1311   -
1312   - string zipfilefullpath = null;
1313   - string tempbackupdirectorypath;
1314   - if (createZip)
1315   - {
1316   - vars[nameof(DBSubstitutionName.DBONAME)] = "";
1317   - vars[nameof(DBSubstitutionName.DBDATAGROUP)] = "";
1318   - string zipfilename = VRH.Common.StringConstructor.ResolveConstructorR(vars, backupfilenamemask, "{}@@") + ".zip";
1319   - zipfilefullpath = Path.Combine(backupdirectorypath, zipfilename);
1320   - tempbackupdirectorypath = Path.Combine(backupdirectorypath, Path.GetRandomFileName());
1321   - if (Directory.Exists(tempbackupdirectorypath)) { Directory.Delete(tempbackupdirectorypath, recursive: true); }
1322   - if (!Directory.Exists(tempbackupdirectorypath)) { Directory.CreateDirectory(tempbackupdirectorypath); }
1323   - }
1324   - else { tempbackupdirectorypath = backupdirectorypath; }
  1727 + vars[nameof(DBSubstitutionName.DBONAME)] = "";
  1728 + vars[nameof(DBSubstitutionName.DBDATAGROUP)] = "";
  1729 + string zipfilename = VRH.Common.StringConstructor.ResolveConstructorR(vars, backupfilenamemask, "{}@@") + ".zip";
  1730 + zipfilefullpath = Path.Combine(backupdirectorypath, zipfilename);
  1731 + tempbackupdirectorypath = Path.Combine(backupdirectorypath, Path.GetRandomFileName());
  1732 + if (Directory.Exists(tempbackupdirectorypath)) { Directory.Delete(tempbackupdirectorypath, recursive: true); }
  1733 + if (!Directory.Exists(tempbackupdirectorypath)) { Directory.CreateDirectory(tempbackupdirectorypath); }
  1734 + }
  1735 + else { tempbackupdirectorypath = backupdirectorypath; }
  1736 +
  1737 + if (!Directory.Exists(backupdirectorypath)) { Directory.CreateDirectory(backupdirectorypath); }
  1738 + var directorynameonly = new DirectoryInfo(backupdirectorypath).Name;
  1739 + var backupfilenameext = Path.GetExtension(backupfilenamemask); if (string.IsNullOrWhiteSpace(backupfilenameext)) { backupfilenameext = ".sql"; }
  1740 + backupfilenamemask = Path.GetFileNameWithoutExtension(backupfilenamemask);
1325 1741  
1326   - if (!Directory.Exists(backupdirectorypath)) { Directory.CreateDirectory(backupdirectorypath); }
1327   - var directorynameonly = new DirectoryInfo(backupdirectorypath).Name;
1328   - var backupfilenameext = Path.GetExtension(backupfilenamemask); if (string.IsNullOrWhiteSpace(backupfilenameext)) { backupfilenameext = ".sql"; }
1329   - backupfilenamemask = Path.GetFileNameWithoutExtension(backupfilenamemask);
  1742 + Server sqlserver = null;
  1743 + try
  1744 + {
  1745 + sqlserver = SQLServerConnect(sqlcs);if (sqlserver == null) { return; }
1330 1746 var sqldatabase = sqlserver.Databases[sqlserver.ConnectionContext.DatabaseName];
1331 1747  
1332 1748 ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, new List<SqlSmoObject> { sqldatabase }, vars);
... ... @@ -1335,11 +1751,11 @@ GO
1335 1751 ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Views.Cast<SqlSmoObject>().ToList(), vars);
1336 1752 ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Tables.Cast<SqlSmoObject>().ToList(), vars);
1337 1753 ScriptOneObject(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldatabase.Triggers.Cast<SqlSmoObject>().ToList(), vars);
1338   - if (createZip) { ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql","", backupts,removearchivedfiles:true, storepathinzip: false); }
  1754 + if (createZip) { ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql", "", backupts, removearchivedfiles: true, storepathinzip: false); }
1339 1755 var resultfilename = zipfilefullpath == null ? "-" : Path.GetFileName(zipfilefullpath);
1340 1756 ColorConsole.WriteLine($"SQL scripts created. DB name:'{dbname}'. BAK/ZIP file name:'{resultfilename}'", ConsoleColor.DarkGreen);
1341 1757 }
1342   - else { ColorConsole.WriteLine($"SQL scripts create: error in db connection string. '{sqlcs}'", ConsoleColor.DarkGreen); }
  1758 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
1343 1759 }
1344 1760 private static void ScriptOneObject(Server sqlserver,string backupdirectory,string backupfilenamemask,List<SqlSmoObject> sqldbobjects,Dictionary<string, string> vars)
1345 1761 {
... ... @@ -1414,60 +1830,62 @@ GO
1414 1830 return;
1415 1831 }
1416 1832 string sqlcs = sqld.SQLCS;
1417   - var sqlserver = SQLServerConnect(sqlcs);
1418 1833 var dbname = GetDBName(sqlcs);
1419   - if (sqlserver != null)
1420   - {
1421   - string backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss");
1422   - bool createZip = sqld.Xml_CreateZip;
1423   - string backupdirectorypath = sqld.Xml_BackupTargetDirectoryPath;
1424   - string backupfilenamemask = sqld.Xml_BackupFileNameMask;
1425 1834  
1426   - var backupfilenameext = Path.GetExtension(backupfilenamemask); if (string.IsNullOrWhiteSpace(backupfilenameext)) { backupfilenameext = ".sql"; }
1427   - backupfilenamemask = Path.GetFileNameWithoutExtension(backupfilenamemask);
  1835 + string backupts = (timestamp.HasValue ? timestamp.Value : DateTime.Now).ToString("yyyyMMddHHmmss");
  1836 + bool createZip = sqld.Xml_CreateZip;
  1837 + string backupdirectorypath = sqld.Xml_BackupTargetDirectoryPath;
  1838 + string backupfilenamemask = sqld.Xml_BackupFileNameMask;
1428 1839  
1429   - var vars = new Dictionary<string, string>();
1430   - vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlcs));
1431   - vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlcs));
1432   - vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts);
1433   - vars.Add(nameof(DBSubstitutionName.DBOTYPE), "TableData");
1434   -
1435   - string zipfilefullpath=null;
1436   - string tempbackupdirectorypath;
1437   - if (createZip)
1438   - {
1439   - vars[nameof(DBSubstitutionName.DBONAME)] = "";
1440   - vars[nameof(DBSubstitutionName.DBDATAGROUP)] = "";
1441   - string zipfilename = VRH.Common.StringConstructor.ResolveConstructorR(vars, backupfilenamemask, "{}@@") + ".zip";
1442   - tempbackupdirectorypath = Path.Combine(backupdirectorypath, Path.GetRandomFileName());
1443   - zipfilefullpath = Path.Combine(backupdirectorypath, zipfilename);
1444   - if (Directory.Exists(tempbackupdirectorypath)) { Directory.Delete(tempbackupdirectorypath, recursive: true); }
1445   - if (!Directory.Exists(tempbackupdirectorypath)) { Directory.CreateDirectory(tempbackupdirectorypath); }
1446   - }
1447   - else { tempbackupdirectorypath = backupdirectorypath; }
  1840 + var backupfilenameext = Path.GetExtension(backupfilenamemask); if (string.IsNullOrWhiteSpace(backupfilenameext)) { backupfilenameext = ".sql"; }
  1841 + backupfilenamemask = Path.GetFileNameWithoutExtension(backupfilenamemask);
  1842 +
  1843 + var vars = new Dictionary<string, string>();
  1844 + vars.Add(nameof(DBSubstitutionName.DATABASE), GetDBName(sqlcs));
  1845 + vars.Add(nameof(DBSubstitutionName.DATASOURCE), GetDataSource(sqlcs));
  1846 + vars.Add(nameof(DBSubstitutionName.BACKUPTS), backupts);
  1847 + vars.Add(nameof(DBSubstitutionName.DBOTYPE), "TableData");
  1848 +
  1849 + string zipfilefullpath=null;
  1850 + string tempbackupdirectorypath;
  1851 + if (createZip)
  1852 + {
  1853 + vars[nameof(DBSubstitutionName.DBONAME)] = "";
  1854 + vars[nameof(DBSubstitutionName.DBDATAGROUP)] = "";
  1855 + string zipfilename = VRH.Common.StringConstructor.ResolveConstructorR(vars, backupfilenamemask, "{}@@") + ".zip";
  1856 + tempbackupdirectorypath = Path.Combine(backupdirectorypath, Path.GetRandomFileName());
  1857 + zipfilefullpath = Path.Combine(backupdirectorypath, zipfilename);
  1858 + if (Directory.Exists(tempbackupdirectorypath)) { Directory.Delete(tempbackupdirectorypath, recursive: true); }
  1859 + if (!Directory.Exists(tempbackupdirectorypath)) { Directory.CreateDirectory(tempbackupdirectorypath); }
  1860 + }
  1861 + else { tempbackupdirectorypath = backupdirectorypath; }
1448 1862  
1449 1863  
1450   - if (!Directory.Exists(backupdirectorypath)) { Directory.CreateDirectory(backupdirectorypath); }
  1864 + if (!Directory.Exists(backupdirectorypath)) { Directory.CreateDirectory(backupdirectorypath); }
1451 1865  
1452 1866  
1453   - List<string> backupfilepathlist = new List<string>();
  1867 + List<string> backupfilepathlist = new List<string>();
  1868 + Server sqlserver = null;
  1869 + try
  1870 + {
  1871 + sqlserver = SQLServerConnect(sqlcs);if (sqlserver == null) { return; }
1454 1872 foreach (var sqldata in sqld.Xml_SQLDataList)
1455 1873 {
1456 1874 vars[nameof(DBSubstitutionName.DBDATAGROUP)] = sqldata.Group;
1457   - var sqlfilescreated = ScriptOneDataGroup(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldata.TableNameList, vars,out List<string> errormessageList);
  1875 + var sqlfilescreated = ScriptOneDataGroup(sqlserver, tempbackupdirectorypath, backupfilenamemask + backupfilenameext, sqldata.TableNameList, vars, out List<string> errormessageList);
1458 1876 backupfilepathlist.AddRange(sqlfilescreated);
1459   - if (errormessageList != null && errormessageList.Any()) { foreach (var emsg in errormessageList) { ColorConsole.WriteLine("\n"+emsg, ConsoleColor.Red); } }
  1877 + if (errormessageList != null && errormessageList.Any()) { foreach (var emsg in errormessageList) { ColorConsole.WriteLine("\n" + emsg, ConsoleColor.Red); } }
1460 1878 }
  1879 + }
  1880 + finally { sqlserver?.ConnectionContext.SqlConnectionObject.Dispose(); }
1461 1881  
1462   - if (createZip)
1463   - {
1464   - string fullpathregex = Regex.Escape(string.Join(";",backupfilepathlist)).Replace(';','|');
1465   - ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql","", fullpathregex, removearchivedfiles: true, storepathinzip: false);
1466   - }
1467   - var resultfilename = zipfilefullpath == null ? "-" : Path.GetFileName(zipfilefullpath);
1468   - ColorConsole.WriteLine($"SQL data scripts created. DB name:'{dbname}'. BAK/ZIP file name:'{resultfilename}'", ConsoleColor.DarkGreen);
  1882 + if (createZip)
  1883 + {
  1884 + string fullpathregex = Regex.Escape(string.Join(";",backupfilepathlist)).Replace(';','|');
  1885 + ZipTools.CreateEntriesFromDirectoryContent(tempbackupdirectorypath, zipfilefullpath, "*.sql","", fullpathregex, removearchivedfiles: true, storepathinzip: false);
1469 1886 }
1470   - else { ColorConsole.WriteLine($"SQL data scripts create: error in db connection string. '{sqlcs}'", ConsoleColor.DarkGreen); }
  1887 + var resultfilename = zipfilefullpath == null ? "-" : Path.GetFileName(zipfilefullpath);
  1888 + ColorConsole.WriteLine($"SQL data scripts created. DB name:'{dbname}'. BAK/ZIP file name:'{resultfilename}'", ConsoleColor.DarkGreen);
1471 1889 }
1472 1890 private static List<string> ScriptOneDataGroup(Server sqlserver, string backupdirectorypath, string backupfilenamemask, List<string> tablenamelist, Dictionary<string, string> vars,out List<string> errormessageList)
1473 1891 {
... ... @@ -1562,8 +1980,7 @@ GO
1562 1980 Xml_BackupFileNameMask = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.BackupFileNameMask), this.RootElement, SQLDataBase.XmlStructure.Attributes.BackupFileNameMask.Values.DEFAULT),
1563 1981 Xml_RestoreFileNameMask = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.RestoreFileNameMask), this.RootElement, SQLDataBase.XmlStructure.Attributes.RestoreFileNameMask.Values.DEFAULT),
1564 1982 Xml_BackupTargetDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.BackupTargetDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.BackupTargetDirectoryPath.Values.DEFAULT),
1565   - Xml_TranzitDirectoryPathLocal = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathLocal), this.RootElement, SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathLocal.Values.DEFAULT),
1566   - Xml_TranzitDirectoryPathNetwork = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathNetwork), this.RootElement, SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPathNetwork.Values.DEFAULT),
  1983 + Xml_TranzitDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.TranzitDirectoryPath.Values.DEFAULT),
1567 1984 Xml_PhysicalFilesDirectoryPath = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.PhysicalFilesDirectoryPath), this.RootElement, SQLDataBase.XmlStructure.Attributes.PhysicalFilesDirectoryPath.Values.DEFAULT),
1568 1985 Xml_ScriptCommandTimeout = GetValue(nameof(SQLDataBase.XmlStructure.Attributes.ScriptCommandTimeout), this.RootElement, SQLDataBase.XmlStructure.Attributes.ScriptCommandTimeout.Values.DEFAULT),
1569 1986 };
... ... @@ -1591,9 +2008,8 @@ GO
1591 2008 public string Xml_BackupFileNameMask;
1592 2009 public string Xml_RestoreFileNameMask;
1593 2010 public string Xml_BackupTargetDirectoryPath;
1594   - public string Xml_TranzitDirectoryPathLocal;
1595   - public bool Xml_IsRemoteDB { get { return !string.IsNullOrWhiteSpace(Xml_TranzitDirectoryPathLocal); } }
1596   - public string Xml_TranzitDirectoryPathNetwork;
  2011 + public bool Xml_IsRemoteDB { get { return !string.IsNullOrWhiteSpace(Xml_TranzitDirectoryPath); } }
  2012 + public string Xml_TranzitDirectoryPath;
1597 2013 public string Xml_SQLConnectionString;
1598 2014 public string Xml_PhysicalFilesDirectoryPath;
1599 2015 public int Xml_ScriptCommandTimeout;
... ... @@ -1625,8 +2041,7 @@ GO
1625 2041 Xml_BackupFileNameMask = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.BackupFileNameMask), sqldatabasexml, common.Xml_BackupFileNameMask);
1626 2042 Xml_RestoreFileNameMask = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.RestoreFileNameMask), sqldatabasexml, common.Xml_RestoreFileNameMask);
1627 2043 Xml_BackupTargetDirectoryPath = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.BackupTargetDirectoryPath), sqldatabasexml, common.Xml_BackupTargetDirectoryPath);
1628   - Xml_TranzitDirectoryPathLocal = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.TranzitDirectoryPathLocal), sqldatabasexml, common.Xml_TranzitDirectoryPathLocal);
1629   - Xml_TranzitDirectoryPathNetwork = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.TranzitDirectoryPathNetwork), sqldatabasexml, common.Xml_TranzitDirectoryPathNetwork);
  2044 + Xml_TranzitDirectoryPath = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.TranzitDirectoryPath), sqldatabasexml, common.Xml_TranzitDirectoryPath);
1630 2045 Xml_SQLConnectionString = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.SQLConnectionString), sqldatabasexml, XmlStructure.SQLDataBase.Attributes.SQLConnectionString.Values.DEFAULT);
1631 2046  
1632 2047 Xml_CreateZip = GetValue(nameof(XmlStructure.SQLDataBase.Attributes.CreateZip), sqldatabasexml, common.Xml_CreateZip);
... ... @@ -1654,8 +2069,7 @@ GO
1654 2069 Xml_BackupFileNameMask = sqld.Xml_BackupFileNameMask;
1655 2070 Xml_RestoreFileNameMask = sqld.Xml_RestoreFileNameMask;
1656 2071 Xml_BackupTargetDirectoryPath = sqld.Xml_BackupTargetDirectoryPath;
1657   - Xml_TranzitDirectoryPathLocal = sqld.Xml_TranzitDirectoryPathLocal;
1658   - Xml_TranzitDirectoryPathNetwork = sqld.Xml_TranzitDirectoryPathNetwork;
  2072 + Xml_TranzitDirectoryPath = sqld.Xml_TranzitDirectoryPath;
1659 2073 Xml_SQLConnectionString = sqld.Xml_SQLConnectionString;
1660 2074 Xml_PhysicalFilesDirectoryPath = sqld.Xml_PhysicalFilesDirectoryPath;
1661 2075 Xml_SQLDataList = sqld.Xml_SQLDataList.Select(x => new SQLData(x)).ToList();
... ... @@ -1670,8 +2084,7 @@ GO
1670 2084 public static class BackupFileNameMask { public static class Values { public const string DEFAULT = ""; } }
1671 2085 public static class RestoreFileNameMask { public static class Values { public const string DEFAULT = ""; } }
1672 2086 public static class BackupTargetDirectoryPath { public static class Values { public const string DEFAULT = ""; } }
1673   - public static class TranzitDirectoryPathLocal { public static class Values { public const string DEFAULT = ""; } }
1674   - public static class TranzitDirectoryPathNetwork { public static class Values { public const string DEFAULT = ""; } }
  2087 + public static class TranzitDirectoryPath { public static class Values { public const string DEFAULT = ""; } }
1675 2088 public static class PhysicalFilesDirectoryPath { public static class Values { public const string DEFAULT = ""; } }
1676 2089 public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } }
1677 2090  
... ... @@ -1688,8 +2101,7 @@ GO
1688 2101 public static class BackupFileNameMask { }
1689 2102 public static class RestoreFileNameMask { }
1690 2103 public static class BackupTargetDirectoryPath { }
1691   - public static class TranzitDirectoryPathLocal { }
1692   - public static class TranzitDirectoryPathNetwork { }
  2104 + public static class TranzitDirectoryPath { }
1693 2105 public static class CreateZip { }
1694 2106 public static class PhysicalFilesDirectoryPath { }
1695 2107 public static class ScriptCommandTimeout { public static class Values { public const int DEFAULT = 10000; } }
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - ScheduledTaskManager.cs
... ... @@ -77,7 +77,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
77 77 ScheduledTaskManagerCore.SetPriority(st.Xml_Name,st.Xml_Priority);
78 78 ColorConsole.WriteLine($"Priority changed for scheduled task. Name:{st.Xml_Name}", ConsoleColor.Green);
79 79 }
80   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  80 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
81 81 }
82 82 return o;
83 83 }
... ... @@ -104,7 +104,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
104 104 ScheduledTaskManagerCore.DisableTask(st.Xml_Name);
105 105 ColorConsole.WriteLine($"Scheduled task disabled. Name:{st.Xml_Name}", ConsoleColor.Green);
106 106 }
107   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  107 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
108 108 }
109 109 return o;
110 110 }
... ... @@ -131,7 +131,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
131 131 ScheduledTaskManagerCore.EnableTask(st.Xml_Name);
132 132 ColorConsole.WriteLine($"Scheduled task enabled. Name:{st.Xml_Name}", ConsoleColor.Green);
133 133 }
134   - catch (Exception ex){ ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  134 + catch (Exception ex){ ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
135 135 }
136 136 return o;
137 137 }
... ... @@ -158,7 +158,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
158 158 ScheduledTaskManagerCore.EndTask(st.Xml_Name);
159 159 ColorConsole.WriteLine($"Scheduled task stopped. Name:{st.Xml_Name}", ConsoleColor.Green);
160 160 }
161   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  161 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
162 162 }
163 163 return o;
164 164 }
... ... @@ -187,7 +187,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
187 187 }
188 188 catch (Exception ex)
189 189 {
190   - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red);
  190 + ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red);
191 191 }
192 192 }
193 193 return o;
... ... @@ -216,7 +216,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
216 216 ScheduledTaskManagerCore.DeleteTask(st.Xml_Name);
217 217 ColorConsole.WriteLine($"Scheduled task uninstalled. Name:{st.Xml_Name}", ConsoleColor.Green);
218 218 }
219   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  219 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
220 220 }
221 221 return o;
222 222 }
... ... @@ -245,7 +245,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ScheduledTaskManagerNS
245 245 ScheduledTaskManagerCore.CreateTask(st);
246 246 ColorConsole.WriteLine($"Scheduled task installed. Name:{st.Xml_Name}", ConsoleColor.Green);
247 247 }
248   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  248 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
249 249 }
250 250 return o;
251 251 }
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - UserManager.cs
... ... @@ -94,7 +94,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS
94 94 ColorConsole.WriteLine($"Action:{cr.Type}, role names: {cr.Roles}.", ConsoleColor.Yellow);
95 95 var sel = ColorConsole.ReadLine($"Press enter to continue.", ConsoleColor.Gray); if (sel.ToUpper() == "EX") return o;
96 96 }
97   - foreach (var rn in cr.RoleArray) { try { MembershipTools.Roles.Create(rn); } catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }; }
  97 + foreach (var rn in cr.RoleArray) { try { MembershipTools.Roles.Create(rn); } catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }; }
98 98 }
99 99 foreach (var cr in iab.GetCreateRoleGroupActions())
100 100 {
... ... @@ -107,7 +107,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS
107 107 {
108 108 MembershipTools.RoleGroups.Create(cr.Name);
109 109 MembershipTools.Assign.RolesToRoleGroups(cr.Roles, cr.Name);
110   - } catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); };
  110 + } catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); };
111 111  
112 112 }
113 113 foreach (var cr in iab.GetCreateUserActions())
... ... @@ -122,11 +122,11 @@ namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS
122 122 {
123 123 MembershipTools.Users.Create(cr.Name, cr.Password, administrator: false, superuser: cr.Superuser, rolenames: cr.RoleArray, rolegroupnames: cr.RoleGroupArray);
124 124 }
125   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); };
  125 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); };
126 126 }
127 127 ColorConsole.WriteLine($"Executing init action block '{iabname}' was successful!", ConsoleColor.Green);
128 128 }
129   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  129 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
130 130 return o;
131 131 }
132 132 #endregion ExecuteInitActionBlock
... ... @@ -144,7 +144,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS
144 144 MembershipTools.Users.Create(suname, supsw, superuser: true);
145 145 ColorConsole.WriteLine($"Creating superuser '{suname}' was successful!", ConsoleColor.Green);
146 146 }
147   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  147 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
148 148 return o;
149 149 }
150 150 #endregion CreateSuperuser
... ... @@ -164,7 +164,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS
164 164 MembershipTools.Users.CreateAdminRolesRoleGroupsUsers(adminun,adminpsw);
165 165 ColorConsole.WriteLine($"Creating admin users was successful!", ConsoleColor.Green);
166 166 }
167   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  167 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
168 168 return o;
169 169 }
170 170 #endregion CreateAdminusers
... ... @@ -184,7 +184,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.UserManagerNS
184 184 }
185 185 else { throw new Exception($"User '{uname}' is protected, can not be deleted!"); }
186 186 }
187   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  187 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
188 188 return o;
189 189 }
190 190 #endregion DeleteUsers
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - WindowsServiceManager.cs
... ... @@ -113,7 +113,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
113 113 var success = WindowsServiceManagerCore.Register(ws, selectedServices.Select(x => x.Name).ToList());
114 114 ColorConsole.WriteLine($"Service registered. Name:{ws.Name}", ConsoleColor.Green);
115 115 }
116   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  116 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
117 117 }
118 118 break;
119 119 case CLP.Module.WindowsServiceManager.Function.Unregister.KEY:
... ... @@ -124,7 +124,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
124 124 var success = WindowsServiceManagerCore.Unregister(ws);
125 125 ColorConsole.WriteLine($"Service unregistered. Name:{ws.Name}", ConsoleColor.Green);
126 126 }
127   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  127 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
128 128 }
129 129 break;
130 130 case CLP.Module.WindowsServiceManager.Function.Start.KEY:
... ... @@ -135,7 +135,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
135 135 var success = WindowsServiceManagerCore.Start(ws.Name, ws.Xml_StartTimeout);
136 136 ColorConsole.WriteLine($"Service started. Name:{ws.Name}", ConsoleColor.Green);
137 137 }
138   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  138 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
139 139 }
140 140 break;
141 141 case CLP.Module.WindowsServiceManager.Function.Stop.KEY:
... ... @@ -146,7 +146,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
146 146 var success = WindowsServiceManagerCore.Stop(ws.Name, ws.Xml_StopTimeout);
147 147 ColorConsole.WriteLine($"Service stopped. Name:{ws.Name}", ConsoleColor.Green);
148 148 }
149   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  149 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
150 150 }
151 151 break;
152 152 case CLP.Module.WindowsServiceManager.Function.Dump.KEY:
... ... @@ -157,7 +157,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
157 157 var success = WindowsServiceManagerCore.Dump(ws.Name);
158 158 ColorConsole.WriteLine($"Service dump completed. Name:{ws.Name}", ConsoleColor.Green);
159 159 }
160   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  160 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
161 161 }
162 162 break;
163 163 case CLP.Module.WindowsServiceManager.Function.Kill.KEY:
... ... @@ -168,7 +168,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
168 168 var success = WindowsServiceManagerCore.Kill(ws.Name);
169 169 ColorConsole.WriteLine($"Service killed. Name:{ws.Name}", ConsoleColor.Green);
170 170 }
171   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  171 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
172 172 }
173 173 break;
174 174 case CLP.Module.WindowsServiceManager.Function.SetUserAccount.KEY: SetUserAccount(config, string.Join(",",selectedkeylist),forcecommandmode:true); break;
... ... @@ -265,7 +265,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
265 265 else { ColorConsole.WriteLine($"Service user account change FAILED! Name:{ws.Name}", ConsoleColor.Red); }
266 266 }
267 267 }
268   - catch (Exception ex) { ColorConsole.WriteLine(ex.Message, ConsoleColor.Red); }
  268 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red); }
269 269 }
270 270 return;
271 271 }
... ... @@ -567,11 +567,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.WindowsServiceManagerNS
567 567 ColorConsole.WriteLine(startInfo.FileName + " " + startInfo.Arguments);
568 568 using (Process exeProcess = Process.Start(startInfo)) { exeProcess.WaitForExit(); }
569 569 }
570   - catch (Exception ex)
571   - {
572   - ColorConsole.WriteLine(ex.Message);
573   - if(ex.InnerException!=null) ColorConsole.WriteLine(ex.InnerException.Message);
574   - }
  570 + catch (Exception ex) { ColorConsole.WriteLine(ex.MessageNested()); }
575 571 return true;
576 572 }
577 573 private static string BuildArgumentListSetDescription(WindowsService ws, List<string> dependencygroupservicenamelist)
... ...
Vrh.Log4Pro.MaintenanceConsole/Program.cs
... ... @@ -92,6 +92,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole
92 92  
93 93 ColorConsole.PressAnykeyToContinue();
94 94 }
  95 + public static ComputerInfo ThisComputer=null;
95 96 }
96 97 public static class TESTS
97 98 {
... ...
Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs
... ... @@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
32 32 // You can specify all the values or you can default the Build and Revision Numbers
33 33 // by using the '*' as shown below:
34 34 // [assembly: AssemblyVersion("1.0.*")]
35   -[assembly: AssemblyVersion("1.26.0.0")]
36   -[assembly: AssemblyFileVersion("1.26.0.0")]
  35 +[assembly: AssemblyVersion("1.27.0.0")]
  36 +[assembly: AssemblyFileVersion("1.27.0.0")]
... ...
Vrh.Log4Pro.MaintenanceConsole/Tools - Http.cs
... ... @@ -38,7 +38,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
38 38 {
39 39 return mode == RequestType.GET? _GetReturninfoJSON(url, timeoutinseconds,out returninfojsonstring) : _PostReturninfoJSON(url, timeoutinseconds, out returninfojsonstring, dictparameterlist);
40 40 }
41   - catch (Exception ex) { return new ReturnInfoJSON() { ReturnValue = -1, ReturnMessage = ex.Message + "\n" + returninfojsonstring, }; }
  41 + catch (Exception ex) { return new ReturnInfoJSON() { ReturnValue = -1, ReturnMessage = ex.MessageNested() + "\n" + returninfojsonstring, }; }
42 42 }
43 43  
44 44 private static ReturnInfoJSON _GetReturninfoJSON(string url, int timeoutinseconds, out string returninfojsonstring)
... ...
Vrh.Log4Pro.MaintenanceConsole/Tools - Membership.cs
... ... @@ -552,7 +552,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
552 552 catch (Exception ex)
553 553 {
554 554 result.ReturnValue = -1;
555   - result.ReturnMessage = ex.Message;
  555 + result.ReturnMessage = ex.MessageNested();
556 556 }
557 557 return result;
558 558 }
... ... @@ -590,7 +590,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
590 590 catch (Exception ex)
591 591 {
592 592 result.ReturnValue = -1;
593   - result.ReturnMessage = ex.Message;
  593 + result.ReturnMessage = ex.MessageNested();
594 594 }
595 595 return result;
596 596 }
... ... @@ -632,7 +632,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
632 632 catch (Exception ex)
633 633 {
634 634 result.ReturnValue = -1;
635   - result.ReturnMessage = ex.Message;
  635 + result.ReturnMessage = ex.MessageNested();
636 636 }
637 637 return result;
638 638 }
... ...
Vrh.Log4Pro.MaintenanceConsole/Tools.cs
... ... @@ -93,7 +93,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
93 93 {
94 94 foreach (var zipentry in archive.Entries)
95 95 {
96   - zipentry.ExtractToFile(targetfilefullpath);
  96 + ColorConsole.WriteLine($"{nameof(Extract1stFileFromZIP)} extracting to file: {targetfilefullpath}", ConsoleColor.Yellow, prefix: "");
  97 + zipentry.ExtractToFile(targetfilefullpath,true);
97 98 return;
98 99 }
99 100 }
... ... @@ -103,9 +104,13 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
103 104 if (!Directory.Exists(targetdirectorypath)) { Directory.CreateDirectory(targetdirectorypath); }
104 105 using (ZipArchive archive = ZipFile.Open(ZIPfilefullpath, ZipArchiveMode.Read))
105 106 {
  107 + ColorConsole.WriteLine();
106 108 foreach (var zipentry in archive.Entries)
107 109 {
108   - zipentry.ExtractToFile(Path.Combine(targetdirectorypath, zipentry.FullName));
  110 + ColorConsole.SetCursorPosition(0, Console.CursorTop);
  111 + string targetfilefullpath = Path.Combine(targetdirectorypath, zipentry.FullName);
  112 + ColorConsole.WriteLine($"{nameof(Extract1stFileFromZIP)} extracting to file: {targetfilefullpath}", ConsoleColor.Yellow, prefix: "");
  113 + zipentry.ExtractToFile(targetfilefullpath,true);
109 114 }
110 115 }
111 116 }
... ... @@ -151,7 +156,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
151 156 catch (Exception ex)
152 157 {
153 158 ColorConsole.WriteLine($"Error when accessing/zipping file '{fi.FullName}'!", ConsoleColor.Red);
154   - ColorConsole.WriteLine(ex.Message, ConsoleColor.Red,prefix: "Exception message: ", bracket:"[]");
  159 + ColorConsole.WriteLine(ex.MessageNested(), ConsoleColor.Red,prefix: "Exception message: ", bracket:"[]");
155 160 }
156 161 }
157 162 cpt = ColorConsole.CursorTop;
... ... @@ -384,7 +389,7 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
384 389 public string OSServicePack;
385 390 public string OSVersionString;
386 391 public List<string> OSFriendlyNames;
387   - public static void DisplayThis() { new ComputerInfo().Display(); }
  392 + public static void DisplayThis() { Program.ThisComputer = Program.ThisComputer??new ComputerInfo(); Program.ThisComputer.Display(); }
388 393 public ComputerInfo()
389 394 {
390 395 var ci = this;
... ... @@ -504,12 +509,14 @@ namespace Vrh.Log4Pro.MaintenanceConsole.ToolsNS
504 509 string indent = "";
505 510 const string indentof1level = " ";
506 511 Exception excl = ex;
507   - while (true)
  512 + while (excl != null)
508 513 {
509   - rexmsg += indent + excl.Message;
  514 + if (!string.IsNullOrWhiteSpace(ex.Message))
  515 + {
  516 + rexmsg += indent + excl.Message;
  517 + indent += (indent == "" ? "\n" : "") + indentof1level;
  518 + }
510 519 excl = excl.InnerException;
511   - indent += (indent==""?"\n":"")+indentof1level;
512   - if (excl == null) { break; }
513 520 }
514 521 return rexmsg.Replace("\n\n","\n");
515 522 }
... ...