среда, 17 июня 2015 г.

1Cv7.7: получение строки соединения с SQL-сервером из файла .dba

Дано: База 1С 7.7 крутится на SQL, необходимо из самой 1С получить имя сервера, чтобы не спрашивать пользователя/заподить константы и т.п.

Решение: дешифровать файл .DBA, в нём хранится как имя сервера и рабочей базы, так и логин-пароль пользователя, под которым подключается 1С.

Под катом 3 ссылки, все утащено на память из указанных источников. В работе используется первый, как самый компактный, хотя и требующий 1С++


Решение 1
Отсюда: http://www.forum.mista.ru/topic.php?id=476168


Процедура Сформировать()
 

    ФайлDBA = СоздатьОбъект("BinaryData");
    Если ФайлDBA.ПодключитьсяКФайлу(КаталогИБ() + "1Cv7.DBA", 1, 1) = 0 Тогда
        Сообщить("Ошибка при открытии файла 1Cv7.DBA. База должна быть SQL");
    КонецЕсли;
    ДанныеDBA = "";
    ФайлDBA.ПрочитатьСтроку(ДанныеDBA);
    КлючSQL = "19465912879oiuxc ensdfaiuo3i73798kjl";
   
    Math = СоздатьОбъект("Math");
    СтрокаСоединения = "";
    Для Ном = 1 По СтрДлина(ДанныеDBA) Цикл
        СтрокаСоединения = СтрокаСоединения + Симв(Math.XOR(КодСимв(Сред(ДанныеDBA, Ном, 1)), КодСимв(Сред(КлючSQL, (Ном-1) % 36 + 1, 1))));
    КонецЦикла;
    СЗ = СоздатьОбъект("СписокЗначений");
    СЗ.ИзСтрокиСРазделителями(СтрЗаменить(СтрЗаменить(СтрокаСоединения, "}", ""), "{", ""));
   
    Сообщить("Сервер SQL: " + СЗ.ПолучитьЗначение(2));
    Сообщить("База данных SQL: " + СЗ.ПолучитьЗначение(4));
    Сообщить("Имя пользователя SQL: " + СЗ.ПолучитьЗначение(6));
    Сообщить("Пароль пользователя SQL: " + СЗ.ПолучитьЗначение(8));

КонецПроцедуры



Решение 2
Отсюда: http://www.forum.mista.ru/topic.php?id=476168

Var Connect;

//*****
Function GetParam(ParamName)
    NamePos = Find(Connect, ParamName);
    If NamePos = 0 Then
        Return "";
    EndIf;
    Connect = Mid(Connect, NamePos + StrLen(ParamName) + 3);
    EndPos = Find(Connect, """");
    Result = Left(Connect, EndPos - 1);
    Connect = Mid(Connect, EndPos + 1);
    Return Result;
EndFunction

//*****
Function XOR(Val ParA, Val ParB)
    Res = 0;
    Koef = 1;
    For BitNumber = 1 To 8 Do
        BitA = ParA % 2;
        BitB = ParB % 2;
        ParA = Int(ParA / 2);
        ParB = Int(ParB / 2);
        BitC = (BitA + BitB) % 2;
        Res = Res + BitC * Koef;
        Koef = Koef * 2;
    EndDo; 
    Return Res;
EndFunction

//*****
Procedure OnOpen()
Var CurDir, SQLKeyCode[36], ConnectCode[200];
    FilePath(CurDir);
    ReturnStatus(0);

    srvList = СоздатьОБъект("СписокЗначений");
   
    //If ValueTypeStr(srvList) <> "СписокЗначений" Then
    //    DoMessageBox("Этот файл используется другими и не может использоваться самостоятельно");
    //    Return;
    //EndIf;
    srvList.Set("Статус", 0);
    ConnectFile = IBDir() + "1Cv7.DBA";
    If FS.ExistFile(ConnectFile) = 0 Then
        Message("Это база не SQL - формата!", "!");
        Form.Close();
        Return;
    EndIF;
    FSO = CreateObject("Scripting.FileSystemObject");
    F = FSO.OpenTextFile(ConnectFile, 1);
    ConnectLen = 0;
    While F.AtEndOfStream = 0 Do
        While F.AtEndOfLine = 0 Do
            ConnectLen = ConnectLen + 1;
            ConnectCode[ConnectLen] = Asc(F.Read(1));
        EndDo;
        If F.AtEndOfStream = 0 Then
            F.SkipLine();
            ConnectLen = ConnectLen + 1;
            ConnectCode[ConnectLen] = 10;
        EndIf;
    EndDo;
    F.Close();
    FSO = 0;
    SQLKey = "19465912879oiuxc ensdfaiuo3i73798kjl";
    For i = 1 To 36 Do
        SQLKeyCode[i] = Asc(Mid(SQLKey, i, 1));
    EndDo;
    Connect = "";
    For i = 1 To ConnectLen Do
        Connect = Connect + Chr(XOR(ConnectCode[i], SQLKeyCode[(i - 1) % 36 + 1]));
    EndDo;
    srvList.Set("Статус", 1);
    srvList.Set("Connect", Connect);
    srvList.Set("ServerName", GetParam("Server"));
    srvList.Set("DBName", GetParam("DB"));
    srvList.Set("User", GetParam("UID"));
    srvList.Set("Password", GetParam("PWD"));
    Message(" - " + srvList.Get("ServerName") + " - " + srvList.Get("DBName") + " - " + srvList.Get("User") + " - " + srvList.Get("Password") + " - ");
EndProcedure



Решение 3.
Отсюда: http://forum.script-coding.com/viewtopic.php?id=358

Функция XOR(Знач ParA, Знач ParB)
    Res = 0;
    Koef = 1;
    Для к=1 По 8 Цикл
        BitA = ParA % 2;
        BitB = ParB % 2;
        ParA = Int(ParA / 2);
        ParB = Int(ParB / 2);
        BitC = (BitA + BitB) % 2;
        Res = Res + BitC * Koef;
        Koef = Koef * 2;
    КонецЦикла;
    Возврат Res;
КонецФункции

//=========================================================
// индексы значений с списке
// server = 2, db = 4, uid = 6, pwd = 8, checksum = 10
Функция СтрокаСоединения(Файл)
    Перем SQLKeyCode[36], ConnectCode[200];
    FSO = CreateObject("Scripting.FileSystemObject");
    F = FSO.OpenTextFile(Файл, 1);
    ConnectLen = 0;
    Пока F.AtEndOfStream = 0 Цикл
        ConnectLen = ConnectLen + 1;
        ConnectCode[ConnectLen] = КодСимв(F.Read(1));
    КонецЦикла;
    F.Close();
    FSO = 0;
    SQLKey = "19465912879oiuxc ensdfaiuo3i73798kjl";
    Для к=1 По 36 Цикл
        SQLKeyCode[к] = КодСимв(Сред(SQLKey, к, 1));
    КонецЦикла;
    Connect = "";
    Для к=1 По ConnectLen Цикл
        Connect = Connect + Симв(XOR(ConnectCode[к], SQLKeyCode[(к - 1) % 36 + 1]));
    КонецЦикла;
    Состояние(Connect);
    vl=СоздатьОбъект("СписокЗначений");
    Connect=СтрЗаменить(Connect,"{","");
    Connect=СтрЗаменить(Connect,"}","");
    vl.ИзСтрокиСРазделителями(Connect);
    Возврат vl;
КонецФункции

Процедура ПриОткрытии()
    сп = СтрокаСоединения(КаталогИБ()+"1cv7.dba");
    зн = "";
    сп.ВыбратьЗначение(зн,,,,0);
КонецПроцедуры

1 комментарий:

Александр комментирует...

Спасибо, Решение 1 помогло разобраться с проблемой.