Initial Commit
This commit is contained in:
482
Systems/SQLServer/General.cs
Normal file
482
Systems/SQLServer/General.cs
Normal file
@@ -0,0 +1,482 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Net;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace Sdaleo.Systems.SQLServer
|
||||
{
|
||||
#region SQLServer General Enums
|
||||
|
||||
/// <summary>
|
||||
/// SQL Server Versions as specified by SQL Server
|
||||
/// </summary>
|
||||
public enum SQLServerVersion
|
||||
{
|
||||
SQL_SERVER_2000 = 80,
|
||||
SQL_SERVER_2005 = 90,
|
||||
SQL_SERVER_2008 = 100,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// General SQL Server Functions
|
||||
/// </summary>
|
||||
public class SQLServerGeneral
|
||||
{
|
||||
#region SQL Version Functions
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the SQL Server Version Information from the specified SQL Server Instance
|
||||
/// (* Prefered Function to use *)
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="version">we pass out the SQL Server Specific Version</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError GetSQLServerVersion(IConnectDb credential, out SQLServerVersion version)
|
||||
{
|
||||
version = SQLServerVersion.SQL_SERVER_2000; // Default behavior
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
int nVersion = (int)SQLServerVersion.SQL_SERVER_2000;
|
||||
DBError dberror = GetSQLServerVersion(credential, out nVersion);
|
||||
if (dberror.ErrorOccured)
|
||||
return dberror;
|
||||
|
||||
// SQLServerVersion numbers are multiple of 10's
|
||||
nVersion = nVersion * 10;
|
||||
try
|
||||
{
|
||||
version = (SQLServerVersion)Enum.Parse(typeof(SQLServerVersion), nVersion.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
dberror = DBError.Create(e.Message);
|
||||
}
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the SQL Server Version String Information from the specified SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="strVersion">we pass out the SQL Server Specific Version String</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError GetSQLServerVersion(IConnectDb credential, out string strVersion)
|
||||
{
|
||||
strVersion = string.Empty;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "EXEC sp_server_info @attribute_id = 2";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
strVersion = retVal.GetDataTableRetVal().Rows[0]["attribute_value"].ToString();
|
||||
strVersion.Replace("\t", ""); // remove tabs
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the SQL Server Version Integer Information from the specified SQL Server Instance
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="nVersion">we pass out the SQL Server Specific Version Int</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError GetSQLServerVersion(IConnectDb credential, out int nVersion)
|
||||
{
|
||||
nVersion = 0;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "SELECT CONVERT(char(20), SERVERPROPERTY('ProductVersion'))";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
if(retVal.IsValid)
|
||||
{
|
||||
string strVersion = retVal.GetScalarRetVal();
|
||||
String[] strVersionSplit = strVersion.Split('.');
|
||||
int.TryParse(strVersionSplit[0], out nVersion);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL File N' Disk functions
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the default path for the SQL Server Instance or for the Database on the SQL Server.
|
||||
/// Leave Database blank in the credential to find the default path for the Server.
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="DefaultPath">default path found or "" if not</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerDefaultPath(IConnectDb credential, out string DefaultPath)
|
||||
{
|
||||
DefaultPath = string.Empty;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Get the Path for the default Path for the Database if Specified
|
||||
string sql = String.Empty;
|
||||
if (credential.DBMS.IsDatabaseSetAndNonSystem)
|
||||
sql = String.Format("SELECT filename FROM [{0}]..sysfiles", credential.DBMS.Database);
|
||||
else
|
||||
sql = "SELECT filename FROM master..sysfiles where [name]='master'";
|
||||
|
||||
// Execute the Query
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.ExecuteScalar(sql);
|
||||
if ((retVal.IsValid) && !String.IsNullOrEmpty(retVal.GetScalarRetVal()))
|
||||
{
|
||||
string strResult = retVal.GetScalarRetVal();
|
||||
int indx = strResult.LastIndexOf('\\');
|
||||
if (indx >= 0)
|
||||
strResult = strResult.Remove(indx);
|
||||
DefaultPath = strResult;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function retries an array of the Fixed HardDrives/Disks that are available on the Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="fixedDisks">an array of all the fixed disk's drive letters (i.e. C), empty list, if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerFixedDisks(IConnectDb credential, out string[] fixedDisks)
|
||||
{
|
||||
fixedDisks = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = "EXEC master..xp_fixeddrives";
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
List<String> retList = new List<String>();
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
retList.Add(row["drive"].ToString());
|
||||
}
|
||||
fixedDisks = retList.ToArray();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function retries an array of directories for the specified Path on the specified SQL Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="Path">a valid path that exists on the server, i.e. C:\Program Files</param>
|
||||
/// <param name="Directories">an array of all directories found in the specified path, empty list if no directories found or if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerGetDirectoriesInPath(IConnectDb credential, string Path, out string[] Directories)
|
||||
{
|
||||
Directories = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("EXEC master..xp_dirtree '{0}', 1, 1", Path);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
List<String> retList = new List<String>();
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
bool bIsDirectory = (row["file"].ToString() == "0");
|
||||
if (bIsDirectory)
|
||||
retList.Add(row["subdirectory"].ToString());
|
||||
}
|
||||
}
|
||||
Directories = retList.ToArray();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Function retries an array of files for the specified Path on the specified SQL Server
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="Path">a valid path that exists on the server, i.e. C:\Program Files</param>
|
||||
/// <param name="Files">an array of all files found in the specified path, empty list if no files found or if error occured</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerGetFilesInPath(IConnectDb credential, string Path, out string[] Files)
|
||||
{
|
||||
Files = null;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute the Query
|
||||
string sql = String.Format("EXEC master..xp_dirtree '{0}', 1, 1", Path);
|
||||
DB db = DB.Create(credential.DBMS.WithoutDatabase());
|
||||
DBRetVal retVal = db.FillDataTable(sql);
|
||||
List<String> retList = new List<String>();
|
||||
if (retVal.IsValid)
|
||||
{
|
||||
foreach (DataRow row in retVal.GetDataTableRetVal().Rows)
|
||||
{
|
||||
bool bIsFile = (row["file"].ToString() == "1");
|
||||
if (bIsFile)
|
||||
retList.Add(row["subdirectory"].ToString());
|
||||
}
|
||||
}
|
||||
Files = retList.ToArray();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Connection Checkers
|
||||
|
||||
/// <summary>
|
||||
/// Quick Check function to see if the passed in credential allows us to connect to the server
|
||||
/// If Credential contains a Database, then it will verify the Database's Existence
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="nConnectionTimeout">Specify the ConnectionTimout</param>
|
||||
/// <param name="CanConnect">Returns true if successfull in connecting to the server</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerCheckConnection(IConnectDb credential, uint nConnectionTimeout, out bool CanConnect)
|
||||
{
|
||||
// the SQL Server should at least have a master db, so this list should never be empty,
|
||||
// if it is, an error must have occured, either with the credential or with the server
|
||||
CanConnect = false;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
// Execute Query
|
||||
string[] Databases = null;
|
||||
DBError dberror = SQLServerDatabase.DatabasesListAll(credential.DBMS.WithoutDatabase().Timeouts.WithConnectionTimeout(nConnectionTimeout), out Databases);
|
||||
if (dberror.ErrorOccured || (Databases == null) || (Databases.Length == 0))
|
||||
CanConnect = false;
|
||||
else
|
||||
CanConnect = true;
|
||||
|
||||
// Check Database Existence, if specified
|
||||
if (CanConnect)
|
||||
{
|
||||
dbError = Validation.IsValidDatabaseName(credential.DBMS.Database);
|
||||
if (!dberror.ErrorOccured)
|
||||
{
|
||||
// Verify that the Database exists
|
||||
bool bFound = false;
|
||||
foreach (string db in Databases)
|
||||
{
|
||||
if (db.ToUpper() == credential.DBMS.Database.ToUpper())
|
||||
{
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Let the Caller know if they can connect to the Database
|
||||
CanConnect = bFound;
|
||||
}
|
||||
}
|
||||
return dberror;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Check function to see if the passed in credential allows us to connect to the
|
||||
/// server, read some data, as well as check SysAdmin Rights for the passed in Credential
|
||||
/// If Credential contains a Database, then it will verify the Database's Existence
|
||||
/// </summary>
|
||||
/// <param name="credential">SQL Server Credentials</param>
|
||||
/// <param name="nConnectionTimeout">Specify the ConnectionTimout</param>
|
||||
/// <param name="IsValid">true, if passed in credential connects and is a sysadmin, false otherwise</param>
|
||||
/// <returns>DBError Object with ErrorOccured, if error Occured</returns>
|
||||
public static DBError SQLServerCheckConnectionNCredential(IConnectDb credential, uint nConnectionTimeout, out bool IsValid)
|
||||
{
|
||||
IsValid = false;
|
||||
DBError dbError = ValidationConsts.IsCredentialValid(credential, DBSystem.SQL_SERVER);
|
||||
if (dbError.ErrorOccured)
|
||||
return dbError;
|
||||
|
||||
DBError dberror = SQLServerCheckConnection(credential, nConnectionTimeout, out IsValid);
|
||||
if (dberror.ErrorOccured || !IsValid)
|
||||
return dberror;
|
||||
|
||||
// Now also make sure that the credential is a SysAdmin
|
||||
dberror = SQLServerSecurity.LoginIsSysAdmin(credential, credential.User, out IsValid);
|
||||
return dberror;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Browse
|
||||
|
||||
/// <summary>
|
||||
/// Returns a array of any found valid SQL Server intances * Using the SQLBrowse Functionallity *
|
||||
/// If SQLBrowse fails, will look in the Registry
|
||||
/// This Function can take a long time, depending on the Network
|
||||
/// </summary>
|
||||
/// <returns>list of valid SQLServers or null if error occured</returns>
|
||||
public static string[] SQLServerNamesAndInstaces()
|
||||
{
|
||||
// Call the SQL Browse Function
|
||||
List<String> validSQLServerInstances = new List<string>();
|
||||
string[] SQLServersRaw = SQLInfoEnumerator.EnumerateSQLServers();
|
||||
foreach (string SQLServerRaw in SQLServersRaw)
|
||||
{
|
||||
// Target name is empty - so add any valid instances found
|
||||
if (Validation.IsValidServerNameAndInstanceName(SQLServerRaw))
|
||||
validSQLServerInstances.Add(SQLServerRaw);
|
||||
}
|
||||
|
||||
// Last thing to try if EnumerateSQLServers() failed is to query the registry
|
||||
// for all possible SQL Server Installations there * and return those *
|
||||
if (validSQLServerInstances.Count == 0)
|
||||
{
|
||||
string strInstalledInstances = RegKey.GetKey<string>(HKEYRoot.LocalMachine, "Microsoft\\Microsoft SQL Server", "InstalledInstances", String.Empty);
|
||||
if (!String.IsNullOrEmpty(strInstalledInstances))
|
||||
{
|
||||
string MachineName = Dns.GetHostName();
|
||||
// Add any Registry Found Instances
|
||||
string[] Instances = strInstalledInstances.Split(' ');
|
||||
foreach (string Instance in Instances)
|
||||
validSQLServerInstances.Add(MachineName + "\\" + Instance);
|
||||
}
|
||||
}
|
||||
return validSQLServerInstances.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Service Functions
|
||||
|
||||
/// <summary>
|
||||
/// Use this to start a SQL Service on the specified Server. You must have Windows admin/SController rights to
|
||||
/// that machine in order for this function to work
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">Name of the SQL Server or SQL ServerNInstance you want to start (required)</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Set to Value > 0 to force a wait for the specified amount of seconds(not required)</param>
|
||||
/// <returns>true if Service was started or was already running, false if an error occured</returns>
|
||||
public static bool SQLServerServiceStart(string ServerOrServerNInstance, int WaitTimeoutInSeconds)
|
||||
{
|
||||
string Server = string.Empty;
|
||||
string Instance = string.Empty;
|
||||
if (String.IsNullOrEmpty(ServerOrServerNInstance))
|
||||
return false;
|
||||
|
||||
if (!SQLServerUtilities.SplitServerOrServerNInstance(ServerOrServerNInstance, out Server, out Instance))
|
||||
return false;
|
||||
|
||||
// Construct the proper service name
|
||||
string Service = string.Empty;
|
||||
if (!String.IsNullOrEmpty(Instance))
|
||||
Service = String.Format("MSSQL${0}", Instance);
|
||||
else
|
||||
Service = "MSSQLSERVER";
|
||||
|
||||
string MachineName = Dns.GetHostName();
|
||||
bool bIsOnThisMachine = (MachineName.ToLower() == Server.ToLower());
|
||||
try
|
||||
{
|
||||
ServiceController service = null;
|
||||
if (bIsOnThisMachine)
|
||||
service = new ServiceController(Service);
|
||||
else
|
||||
service = new ServiceController(Service, Server);
|
||||
|
||||
bool bStartService = (service.Status != ServiceControllerStatus.Running);
|
||||
if (bStartService)
|
||||
{
|
||||
service.Start();
|
||||
if (WaitTimeoutInSeconds > 0)
|
||||
{
|
||||
TimeSpan timeout = TimeSpan.FromSeconds(WaitTimeoutInSeconds);
|
||||
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
|
||||
return (service.Status == ServiceControllerStatus.Running);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to stop a SQL Service on the specified Server. You must have Windows admin/SController rights to
|
||||
/// that machine in order for this function to work
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">Name of the SQL Server or SQL ServerNInstance you want to stop (required)</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Set to Value > 0 to force a wait for the specified amount of seconds(not required)</param>
|
||||
/// <returns>true if Service was stopped or was already stopped, false if an error occured</returns>
|
||||
public static bool SQLServerServiceStop(string ServerOrServerNInstance, int WaitTimeoutInSeconds)
|
||||
{
|
||||
string Server = string.Empty;
|
||||
string Instance = string.Empty;
|
||||
if (String.IsNullOrEmpty(ServerOrServerNInstance))
|
||||
return false;
|
||||
|
||||
if (!SQLServerUtilities.SplitServerOrServerNInstance(ServerOrServerNInstance, out Server, out Instance))
|
||||
return false;
|
||||
|
||||
// Construct the proper service name
|
||||
string Service = string.Empty;
|
||||
if (!String.IsNullOrEmpty(Instance))
|
||||
Service = String.Format("MSSQL${0}", Instance);
|
||||
else
|
||||
Service = "MSSQLSERVER";
|
||||
|
||||
string MachineName = Dns.GetHostName();
|
||||
bool bIsOnThisMachine = (MachineName.ToLower() == Server.ToLower());
|
||||
try
|
||||
{
|
||||
ServiceController service = null;
|
||||
if (bIsOnThisMachine)
|
||||
service = new ServiceController(Service);
|
||||
else
|
||||
service = new ServiceController(Service, Server);
|
||||
|
||||
bool bStopService = (service.Status != ServiceControllerStatus.Stopped);
|
||||
if (bStopService)
|
||||
{
|
||||
service.Stop();
|
||||
if (WaitTimeoutInSeconds > 0)
|
||||
{
|
||||
TimeSpan timeout = TimeSpan.FromSeconds(WaitTimeoutInSeconds);
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
|
||||
return (service.Status == ServiceControllerStatus.Stopped);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to restart a SQL Service on the specified Server. You must have Windows admin/SController rights to
|
||||
/// that machine in order for this function to work
|
||||
/// </summary>
|
||||
/// <param name="ServerOrServerNInstance">Name of the SQL Server or SQL ServerNInstance you want to restart (required)</param>
|
||||
/// <param name="WaitTimeoutInSeconds">Set to Value > 0 to force a wait for the specified amount of seconds(not required)</param>
|
||||
/// <returns>true if Service was restared successfully, false if an error occured</returns>
|
||||
public static bool SQLServerServiceRestart(string ServerOrServerNInstance, int WaitTimeoutInSeconds)
|
||||
{
|
||||
return SQLServerServiceStop(ServerOrServerNInstance, WaitTimeoutInSeconds) && SQLServerServiceStart(ServerOrServerNInstance, WaitTimeoutInSeconds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user