При разработке настольных приложений на Windows(WinForms) Вам может потребоваться подключаться к разным SQL серверам. Часто фигурирует название строка соединения (connection string). В Microsoft эти соединения хранятся в файле app.config. А что делать, если соединений очень много. Выход один нужно разработать свой интерфейс. Пример Главной формы (код формы 0103) по тестированию строк соединений указан ниже.
В дальнейшем при компиляции программ, файл app.config переименовывается в название библиотеки или exe файла. Открыть файл можно через кнопку "Открыть XML файл соединения". Выглядит он так
Файл можно редактировать вручную, но остается проблема ручного ввода данных по строкам соединения. Как проверить их и правильно ввести в XML файл. В этом случае можно воспользоваться кнопкой "Подобрать соединение". Перед вами отобразится графический интерфейс для подбора соединений
Выбрав поставщика данных, базу данных, реквизиты доступа вы сможете проверить соединение и в случае успеха нажать OK. Вот и все, данные быстро передадутся в Главную форму и Вам останется повторно все протестировать. Это желтая кнопка с информацией "Начать проверку соединения".
Соединение проверяется асинхронно. Пример кода на C# указан ниже.
class Verify
{
static FormConnection frmMessage = null;
// Проверка соединений
public static async void ConnectServer(string FormName = "", string StringConnection = "")
{
frmMessage = new FormConnection();
frmMessage.Show();
TextBox status = frmMessage.textBoxStatus;
// Находим строку соединений.
if (StringConnection == "")
StringConnection = Utils.GetConnectionString("NavigatorConnectionString");
// В конфигурации не определено соединение NavigatorConnectionString
if (StringConnection == "")
{
status.Text = Environment.NewLine + "Соединение с именем NavigatorConnectionString не найдено!";
status.ForeColor = System.Drawing.Color.Red;
return;
}
status.Text = Environment.NewLine + "Ждите ... Проверяется соединение с базой данных";
status.ForeColor = System.Drawing.Color.Black;
frmMessage.Refresh();
// Проверяем асинхронную загрузку
string msg = await CheckConnectionAsync(StringConnection);
if (msg == "")
{
status.Text = Environment.NewLine + "Соединение с базой УСТАНОВЛЕНО.";
status.ForeColor = System.Drawing.Color.DarkGreen;
if (FormName != "") {
frmMessage.Close();
if (FormName == "FormEditorReports")
{
// Открываем форму и передаем строку соединения
NavigatorReports.Utils.OpenForm("FormEditorReports", StringConnection);
}
else if (FormName == "FormEditorFiles")
{
NavigatorFiles.Utils.OpenForm("FormEditorFiles", StringConnection);
}
}
}
else
{
// Ошибка соединения с базой данных
status.Text = "Соединение с базой НЕ установлено. " + msg + Environment.NewLine + "Строка соединения: " + StringConnection;
status.ForeColor = System.Drawing.Color.Red;
}
}
public static async Task<string> CheckConnectionAsync(string connectionString)
{
try
{
if (connectionString.Contains("OLEDB"))
{
using (OleDbConnection myConnection = new OleDbConnection(connectionString))
try
{
await myConnection.OpenAsync();
return "";
}
catch (Exception ex)
{
return ex.Message;
}
}
// Проверка соединения ODBC
else if (connectionString.Contains("ODBC"))
{
using (OdbcConnection myConnection = new OdbcConnection(connectionString))
try
{
await myConnection.OpenAsync();
//Thread.Sleep(1000);
var cmd = myConnection.CreateCommand();
return "";
}
catch (Exception ex)
{
return ex.Message;
}
}
using (SqlConnection myConnection = new SqlConnection(connectionString))
try
{
// Разбираем на части строку соединения
await myConnection.OpenAsync();
// Отсоединяем базу данных
if (connectionString.Contains("AttachDBFilename"))
{
//SqlConnectionStringBuilder decoder = new SqlConnectionStringBuilder(connectionString);
//var cmd = myConnection.CreateCommand();
//cmd.CommandText = sp_detach_db(decoder.AttachDBFilename);
//await cmd.ExecuteScalarAsync();
}
return "";
}
catch (Exception ex)
{
return ex.Message;
}
}
catch (Exception e)
{
return e.Message;
}
//return "";
}
// Отсоединить базу данных
public static string sp_detach_db(string mdf)
{
string SQL = "USE master; ALTER DATABASE[{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE;" +
"EXEC sp_detach_db '{0}';";
return SQL.Replace("{0}", mdf);
}
Также через кнопку "За(рас)шифровать соединение" вы можете зашифровать в файле confg нужное соединение. Это делается в том случае, если этой базой будут пользоваться другие пользователи, и они смогут прочитать строку соединения. Это очень плохо, даже, если они и не являются специалистами по базам данных. Код для расшифровки и зашифровки строки соединения
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace NavigatorForms.Test
{
public class Prot
{
// Зашифровываем текст
public static string Encrypt(string encryptString, string EncryptionKey)
{
byte[] clearBytes = Encoding.Unicode.GetBytes(encryptString);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] {0x24, 0x31, 0x64 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
encryptString = Convert.ToBase64String(ms.ToArray());
}
}
return encryptString;
}
// Расшифровываем текст
public static string Decrypt(string cipherText, string EncryptionKey)
{
cipherText = cipherText.Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x24, 0x31, 0x64 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
}
}
Вообще можно просто купить эту форму. Ориентировочная Цена 500 рублей. Эту форму можно доработать и вставить в свою программу. Это намного быстрее и дешевле, чем самому придумывать интерфейс.